Whamcloud - gitweb
- add mballoc to ldiskfs series
[fs/lustre-release.git] / lustre / utils / lconf
index 6319775..08cd122 100755 (executable)
@@ -58,7 +58,7 @@ DEFAULT_PORT = 988
 # Maximum number of devices to search for.
 # (the /dev/loop* nodes need to be created beforehand)
 MAX_LOOP_DEVICES = 256
-PORTALS_DIR = 'portals'
+PORTALS_DIR = '../portals'
 
 # Needed to call lconf --record
 CONFIG_FILE = "" 
@@ -90,6 +90,9 @@ ptldebug_names = {
     "reada" :     (1 << 22),
     "mmap" :      (1 << 23),
     "config" :    (1 << 24),
+    "console" :   (1 << 25),
+    "quota" :     (1 << 26),
+    "sec" :       (1 << 27),
 }
 
 subsystem_names = {
@@ -104,22 +107,21 @@ subsystem_names = {
     "rpc" :          (1 << 8),
     "mgmt" :         (1 << 9),
     "portals" :      (1 << 10),
-    "socknal" :      (1 << 11),
-    "qswnal" :       (1 << 12),
-    "pinger" :       (1 << 13),
-    "filter" :       (1 << 14),
-    "ptlbd" :        (1 << 15),
-    "echo" :         (1 << 16),
-    "ldlm" :         (1 << 17),
-    "lov" :          (1 << 18),
-    "gmnal" :        (1 << 19),
-    "ptlrouter" :    (1 << 20),
-    "cobd" :         (1 << 21),
-    "ibnal" :        (1 << 22),
-    "sm" :           (1 << 23),
-    "asobd" :        (1 << 24),
-    "lmv" :          (1 << 25),
-    "cmobd" :        (1 << 26),
+    "nal" :          (1 << 11),
+    "pinger" :       (1 << 12),
+    "filter" :       (1 << 13),
+    "ptlbd" :        (1 << 14),
+    "echo" :         (1 << 15),
+    "ldlm" :         (1 << 16),
+    "lov" :          (1 << 17),
+    "ptlrouter" :    (1 << 18),
+    "cobd" :         (1 << 19),
+    "sm" :           (1 << 20),
+    "asobd" :        (1 << 21),
+    "confobd" :      (1 << 22),
+    "lmv" :          (1 << 23),
+    "cmobd" :        (1 << 24),
+    "sec" :          (1 << 25),
     }
 
 
@@ -219,8 +221,11 @@ class DaemonHandler:
         if self.running():
             pid = self.read_pidfile()
             try:
-                log ("killing process", pid)
-                os.kill(pid, 15)
+               if pid != 1:
+                   log ("killing process", pid)
+                   os.kill(pid, 15)
+               else:
+                   log("was unable to find pid of " + self.command)
                 #time.sleep(1) # let daemon die
             except OSError, e:
                 log("unable to kill", self.command, e)
@@ -231,7 +236,10 @@ class DaemonHandler:
         pid = self.read_pidfile()
         if pid:
             try:
-                os.kill(pid, 0)
+               if pid != 1:
+                   os.kill(pid, 0)
+               else:
+                   log("was unable to find pid of " + self.command)
             except OSError:
                 self.clean_pidfile()
             else:
@@ -241,7 +249,10 @@ class DaemonHandler:
     def read_pidfile(self):
         try:
             fp = open(self.pidfile(), 'r')
-            pid = int(fp.read())
+           val = fp.read()
+           if val == '':
+               val = '1'
+            pid = int(val)
             fp.close()
             return pid
         except IOError:
@@ -402,7 +413,6 @@ class LCTLInterface:
             raise CommandError(self.lctl, out, rc)
         return rc, out
 
-            
     def clear_log(self, dev, log):
         """ clear an existing log """
         cmds =  """
@@ -451,24 +461,31 @@ class LCTLInterface:
         self.run(cmds)
 
     def add_peer(self, net_type, nid, hostaddr, port):
-        if net_type  in ('tcp',) and not config.lctl_dump:
+        if net_type  in ('tcp','openib','ra') and not config.lctl_dump:
             cmds =  """
   network %s
   add_peer %s %s %d
   quit""" % (net_type,
              nid, hostaddr, port )
             self.run(cmds)
-        elif net_type in ('openib','iib',) and not config.lctl_dump:
+        elif net_type in ('iib',) and not config.lctl_dump:
             cmds =  """
   network %s
   add_peer %s
   quit""" % (net_type,
              nid )
             self.run(cmds)
+        elif net_type in ('vib',) and not config.lctl_dump:
+            cmds =  """
+  network %s
+  add_peer %s %s
+  quit""" % (net_type,
+             nid, hostaddr )
+            self.run(cmds)
     
     def connect(self, srv):
         self.add_uuid(srv.net_type, srv.nid_uuid, srv.nid)
-        if srv.net_type  in ('tcp','openib','iib',) and not config.lctl_dump:
+        if srv.net_type  in ('tcp','openib','iib','vib','ra') and not config.lctl_dump:
             if srv.hostaddr[0]:
                 hostaddr = string.split(srv.hostaddr[0], '/')[0]
             self.add_peer(srv.net_type, srv.nid, hostaddr, srv.port)
@@ -535,7 +552,7 @@ class LCTLInterface:
   quit""" % (net_type,
              nid, hostaddr)
                 self.run(cmds)
-        elif net_type  in ('openib','iib',) and not config.lctl_dump:
+        elif net_type  in ('openib','iib','vib','ra') and not config.lctl_dump:
                 cmds =  """
   ignore_errors
   network %s
@@ -547,7 +564,7 @@ class LCTLInterface:
     # disconnect one connection
     def disconnect(self, srv):
         self.del_uuid(srv.nid_uuid)
-        if srv.net_type  in ('tcp','openib','iib',) and not config.lctl_dump:
+        if srv.net_type  in ('tcp','openib','iib','vib','ra') and not config.lctl_dump:
             if srv.hostaddr[0]:
                 hostaddr = string.split(srv.hostaddr[0], '/')[0]
             self.del_peer(srv.net_type, srv.nid, hostaddr)
@@ -574,6 +591,20 @@ class LCTLInterface:
   quit""" % (type, name, uuid)
         self.run(cmds)
         
+    def detach(self, name):
+        cmds = """
+  cfg_device %s
+  detach
+  quit""" % (name)
+        self.run(cmds)
+        
+    def set_security(self, name, key, value):
+        cmds = """
+  cfg_device %s
+  set_security %s %s
+  quit""" % (name, key, value)
+        self.run(cmds)
+
     def setup(self, name, setup = ""):
         cmds = """
   cfg_device %s
@@ -588,17 +619,23 @@ class LCTLInterface:
   quit""" % (name, conn_uuid)
         self.run(cmds)
 
+    def start(self, name, conf_name):
+        cmds = """
+  device $%s
+  start %s
+  quit""" % (name, conf_name)
+        self.run(cmds)
 
     # create a new device with lctl
     def newdev(self, type, name, uuid, setup = ""):
-        self.attach(type, name, uuid);
+        if type != 'mds':
+            self.attach(type, name, uuid);
         try:
             self.setup(name, setup)
         except CommandError, e:
             self.cleanup(name, uuid, 0)
             raise e
         
-
     # cleanup a device
     def cleanup(self, name, uuid, force, failover = 0):
         if failover: force = 1
@@ -763,17 +800,6 @@ def do_find_file(base, mod):
             if module:
                 return module
 
-def find_module(src_dir, dev_dir, modname):
-    modbase = src_dir +'/'+ dev_dir +'/'+ modname
-    for modext in '.ko', '.o':
-        module = modbase + modext
-        try: 
-            if os.access(module, os.R_OK):
-                return module
-        except OSError:
-            pass
-    return None
-
 # is the path a block device?
 def is_block(path):
     s = ()
@@ -918,8 +944,19 @@ def find_assigned_loop(file):
                 m = re.search(r'\((.*)\)', out[0])
                 if m and file == m.group(1):
                     return dev
-        else:
-            break
+    return ''
+
+# find free loop device
+def find_free_loop(file):
+    loop = loop_base()
+    
+    # find next free loop
+    for n in xrange(0, MAX_LOOP_DEVICES):
+        dev = loop + str(n)
+        if os.access(dev, os.R_OK):
+            (stat, out) = run('losetup', dev)
+            if stat:
+                return dev
     return ''
 
 # create file if necessary and assign the first free loop device
@@ -938,43 +975,45 @@ def init_loop(file, size, fstype, journal_size, inode_size,
             
     dev = find_assigned_loop(realfile)
     if dev:
-        print 'WARNING file:', realfile, 'already mapped to', dev
-        return dev
+        print 'WARNING: file', realfile, 'already mapped to', dev
+       return dev
             
     if reformat or not os.access(realfile, os.R_OK | os.W_OK):
-        if size < 8000:
-            panic("size of loopback file '%s' must be larger than 8MB, but is set to %s" % (realfile, size))
         (ret, out) = run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, realfile))
         if ret:
             panic("Unable to create backing store:", realfile)
-            
         mkfs(realfile, size, realfstype, journal_size, inode_size, 
              mkfsoptions, isblock=0)
 
-    loop = loop_base()
-    # find next free loop
-    for n in xrange(0, MAX_LOOP_DEVICES):
-        dev = loop + str(n)
-        if os.access(dev, os.R_OK):
-            (stat, out) = run('losetup', dev)
-            if stat:
-                run('losetup', dev, realfile)
-                return dev
-        else:
-            print "out of loop devices"
-            return ''
+    dev = find_free_loop(realfile)
+    if dev:
+       print "attach " + realfile + " <-> " + dev                  
+        run('losetup', dev, realfile)
+        return dev
+
     print "out of loop devices"
     return ''
 
 # undo loop assignment
-def clean_loop(file):
-    dev = find_assigned_loop(file)
-    if dev:
-        ret, out = run('losetup -d', dev)
-        if ret:
-            log('unable to clean loop device:', dev, 'for file:', file)
-            logall(out)
-
+def clean_loop(dev, fstype, backfstype, backdev):
+    if fstype == 'smfs':
+       realfile = backdev
+    else:
+       realfile = dev
+    if not is_block(realfile):
+       dev = find_assigned_loop(realfile)
+       if dev:
+           print "detach " + dev + " <-> " + realfile
+           ret, out = run('losetup -d', dev)
+           if ret:
+               log('unable to clean loop device', dev, 'for file', realfile)
+               logall(out)
+
+# finilizes passed device
+def clean_dev(dev, fstype, backfstype, backdev):
+    if fstype == 'smfs' or not is_block(dev):
+       clean_loop(dev, fstype, backfstype, backdev)
+       
 # determine if dev is formatted as a <fstype> filesystem
 def need_format(fstype, dev):
     # FIXME don't know how to implement this    
@@ -1014,6 +1053,8 @@ def def_mount_options(fstype, target):
         mountfsoptions = "errors=remount-ro"
         if target == 'ost' and sys_get_branch() == '2.4':
             mountfsoptions = "%s,asyncdel" % (mountfsoptions)
+        if target == 'ost' and sys_get_branch() == '2.6':
+            mountfsoptions = "%s,extents,mballoc" % (mountfsoptions)
         return mountfsoptions
     return ""
         
@@ -1038,7 +1079,7 @@ def sys_get_local_nid(net_type, wildcard, cluster_id):
 def sys_get_local_address(net_type, wildcard, cluster_id):
     """Return the local address for the network type."""
     local = ""
-    if net_type in ('tcp','openib','iib',):
+    if net_type in ('tcp','openib','iib','vib','ra'):
         if  ':' in wildcard:
             iface, star = string.split(wildcard, ':')
             local = if2addr(iface)
@@ -1068,6 +1109,8 @@ def sys_get_local_address(net_type, wildcard, cluster_id):
                 local = elan_id
         except IOError, e:
             log(e)
+    elif net_type == 'lo':
+        fixme("automatic local address for loopback")
     elif net_type == 'gm':
         fixme("automatic local address for GM")
 
@@ -1088,20 +1131,6 @@ def sys_get_branch():
         log(e)
     return ""
 
-
-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:
-        return 0
-
 # XXX: instead of device_list, ask for $name and see what we get
 def is_prepared(name):
     """Return true if a device exists for the name"""
@@ -1120,7 +1149,7 @@ def is_prepared(name):
         e.dump()
     return 0
 
-def is_network_prepared():
+def net_is_prepared():
     """If the any device exists, then assume that all networking
        has been configured"""
     out = lctl.device_list()
@@ -1139,57 +1168,163 @@ def fs_is_mounted(path):
     except IOError, e:
         log(e)
     return 0
-        
+
+def kmod_find(src_dir, dev_dir, modname):
+    modbase = src_dir +'/'+ dev_dir +'/'+ modname
+    for modext in '.ko', '.o':
+        module = modbase + modext
+        try:
+            if os.access(module, os.R_OK):
+                return module
+        except OSError:
+               pass
+    return None
+
+def kmod_info(modname):
+    """Returns reference count for passed module name."""
+    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[0] == mod,
+                    map(lambda line: string.split(line), lines))
+       if not ret:
+           return ''
+       return ret[0]
+    except Exception, e:
+        return 0
 
 class kmod:
+    """Presents kernel module"""
+    def __init__(self, src_dir, dev_dir, name):
+        self.src_dir = src_dir
+        self.dev_dir = dev_dir
+        self.name = name
+
+    # FIXME we ignore the failure of loading gss module, because we might
+    # don't need it at all.
+    def load(self):
+        """Load module"""
+        log ('loading module:', self.name, 'srcdir',
+             self.src_dir, 'devdir', self.dev_dir)
+        if self.src_dir:
+            module = kmod_find(self.src_dir, self.dev_dir,
+                               self.name)
+            if not module and self.name != 'ptlrpcs_gss':
+                panic('module not found:', self.name)
+            (rc, out)  = run('/sbin/insmod', module)
+            if rc:
+                if self.name == 'ptlrpcs_gss':
+                    print "Warning: not support gss security!"
+                else:
+                    raise CommandError('insmod', out, rc)
+        else:
+            (rc, out) = run('/sbin/modprobe', self.name)
+            if rc:
+                if self.name == 'ptlrpcs_gss':
+                    print "Warning: not support gss security!"
+                else:
+                    raise CommandError('modprobe', out, rc)
+
+    def cleanup(self):
+       """Unload module"""
+        log('unloading module:', self.name)
+        (rc, out) = run('/sbin/rmmod', self.name)
+        if rc:
+            log('unable to unload module:', self.name +
+                "(" + self.refcount() + ")")
+            logall(out)
+
+    def info(self):
+        """Returns module info if any."""
+        return kmod_info(self.name)
+
+    def loaded(self):
+        """Returns 1 if module is loaded. Otherwise 0 is returned."""
+        if self.info():
+            return 1
+        else:
+            return 0
+
+    def refcount(self):
+        """Returns module refcount."""
+        info = self.info()
+        if not info:
+            return ''
+        return info[2]
+
+    def used(self):
+        """Returns 1 if module is used, otherwise 0 is returned."""
+        info = self.info()
+        if not info:
+            return 0
+        if len(info) > 3:
+            users = info[3]
+            if users and users != '(unused)' and users != '-':
+                return 1
+            else:
+                return 0
+        else:
+            return 0
+
+    def busy(self):
+        """Returns 1 if module is busy, otherwise 0 is returned."""
+        if self.loaded() and (self.used() or self.refcount() != '0'):
+            return 1
+        else:
+            return 0
+
+class kmod_manager:
     """Manage kernel modules"""
     def __init__(self, lustre_dir, portals_dir):
         self.lustre_dir = lustre_dir
         self.portals_dir = portals_dir
         self.kmodule_list = []
 
+    def find_module(self, modname):
+        """Find module by module name"""
+        for mod in self.kmodule_list:
+            if mod.name == modname:
+                return mod
+        return ''
+        
     def add_portals_module(self, dev_dir, modname):
         """Append a module to list of modules to load."""
-        self.kmodule_list.append((self.portals_dir, dev_dir, modname))
+
+        mod = self.find_module(modname)
+        if not mod:
+            mod = kmod(self.portals_dir, dev_dir, modname)
+            self.kmodule_list.append(mod)
 
     def add_lustre_module(self, dev_dir, modname):
         """Append a module to list of modules to load."""
-        self.kmodule_list.append((self.lustre_dir, dev_dir, modname))
 
-    def load_module(self):
+        mod = self.find_module(modname)
+        if not mod:
+            mod = kmod(self.lustre_dir, dev_dir, modname)
+            self.kmodule_list.append(mod)
+        
+    def load_modules(self):
         """Load all the modules in the list in the order they appear."""
-        for src_dir, dev_dir, mod in self.kmodule_list:
-            if mod_loaded(mod) and not config.noexec:
+        for mod in self.kmodule_list:
+            if mod.loaded() and not config.noexec:
                 continue
-            log ('loading module:', mod, 'srcdir', src_dir, 'devdir', dev_dir)
-            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:
-                    raise CommandError('insmod', out, rc)
-            else:
-                (rc, out) = run('/sbin/modprobe', mod)
-                if rc:
-                    raise CommandError('modprobe', out, rc)
+            mod.load()
 
-    def cleanup_module(self):
+    def cleanup_modules(self):
         """Unload the modules in the list in reverse order."""
         rev = self.kmodule_list
         rev.reverse()
-        for src_dir, dev_dir, mod in rev:
-            if not mod_loaded(mod) and not config.noexec:
+        for mod in rev:
+            if (not mod.loaded() or mod.busy()) and not config.noexec:
                 continue
             # debug hack
-            if mod == 'portals' and config.dump:
+            if mod.name == 'portals' and config.dump:
                 lctl.dump(config.dump)
-            log('unloading module:', mod)
-            (rc, out) = run('/sbin/rmmod', mod)
-            if rc:
-                log('! unable to unload module:', mod)
-                logall(out)
-
+            mod.cleanup()
+           
 # ============================================================
 # Classes to prepare and cleanup the various objects
 #
@@ -1204,8 +1339,7 @@ class Module:
         self.uuid = self.db.getUUID()
         self._server = None
         self._connected = 0
-        self.kmod = kmod(config.lustre, config.portals)
-        
+
     def info(self, *args):
         msg = string.join(map(str,args))
         print self.module_name + ":", self.name, self.uuid, msg
@@ -1219,27 +1353,14 @@ class Module:
             log(self.module_name, "cleanup failed: ", self.name)
             e.dump()
             cleanup_error(e.rc)
-            
-    def add_portals_module(self, dev_dir, modname):
-        """Append a module to list of modules to load."""
-        self.kmod.add_portals_module(dev_dir, modname)
 
-    def add_lustre_module(self, dev_dir, modname):
-        """Append a module to list of modules to load."""
-        self.kmod.add_lustre_module(dev_dir, modname)
-
-    def load_module(self):
-        """Load all the modules in the list in the order they appear."""
-        self.kmod.load_module()
-            
-    def cleanup_module(self):
-        """Unload the modules in the list in reverse order."""
-        if self.safe_to_clean():
-            self.kmod.cleanup_module()
+    def add_module(self, manager):
+        """Adds all needed modules in the order they appear."""
+        return
 
     def safe_to_clean(self):
         return 1
-        
+
     def safe_to_clean_modules(self):
         return self.safe_to_clean()
         
@@ -1261,7 +1382,6 @@ class Network(Module):
             self.generic_nid = 0
 
         self.nid_uuid = self.nid_to_uuid(self.nid)
-
         self.hostaddr = self.db.get_hostaddr()
         if len(self.hostaddr) == 0:
             self.hostaddr.append(self.nid)
@@ -1271,26 +1391,34 @@ class Network(Module):
                 panic("unable to set hostaddr for", self.net_type, self.hostaddr[0], self.cluster_id)
             debug("hostaddr:", self.hostaddr[0])
 
-        self.add_portals_module("libcfs", 'libcfs')
-        self.add_portals_module("portals", 'portals')
-        if node_needs_router():
-            self.add_portals_module("router", 'kptlrouter')
+    def add_module(self, manager):
+        manager.add_portals_module("libcfs", 'libcfs')
+        manager.add_portals_module("portals", 'portals')
+        
+       if node_needs_router():
+            manager.add_portals_module("router", 'kptlrouter')
         if self.net_type == 'tcp':
-            self.add_portals_module("knals/socknal", 'ksocknal')
+            manager.add_portals_module("knals/socknal", 'ksocknal')
         if self.net_type == 'elan':
-            self.add_portals_module("knals/qswnal", 'kqswnal')
+            manager.add_portals_module("knals/qswnal", 'kqswnal')
         if self.net_type == 'gm':
-            self.add_portals_module("knals/gmnal", 'kgmnal')
+            manager.add_portals_module("knals/gmnal", 'kgmnal')
         if self.net_type == 'openib':
-            self.add_portals_module("knals/openibnal", 'kopenibnal')
+            manager.add_portals_module("knals/openibnal", 'kopenibnal')
         if self.net_type == 'iib':
-            self.add_portals_module("knals/iibnal", 'kiibnal')
+            manager.add_portals_module("knals/iibnal", 'kiibnal')
+        if self.net_type == 'vib':
+            self.add_portals_module("knals/vibnal", 'kvibnal')
+        if self.net_type == 'lo':
+            manager.add_portals_module("knals/lonal", 'klonal')
+        if self.net_type == 'ra':
+            manager.add_portals_module("knals/ranal", 'kranal')
 
     def nid_to_uuid(self, nid):
         return "NID_%s_UUID" %(nid,)
 
     def prepare(self):
-        if not config.record and is_network_prepared():
+        if not config.record and net_is_prepared():
             return
         self.info(self.net_type, self.nid, self.port)
         if not (config.record and self.generic_nid):
@@ -1338,7 +1466,7 @@ class Network(Module):
                                 cleanup_error(e.rc)
 
     def safe_to_clean(self):
-        return not is_network_prepared()
+        return not net_is_prepared()
 
     def cleanup(self):
         self.info(self.net_type, self.nid, self.port)
@@ -1362,7 +1490,7 @@ class RouteTable(Module):
                          lo, hi):
         # only setup connections for tcp, openib, and iib NALs
         srvdb = None
-        if not net_type in ('tcp','openib','iib',):
+        if not net_type in ('tcp','openib','iib','vib','ra'):
             return None
 
         # connect to target if route is to single node and this node is the gw
@@ -1384,7 +1512,7 @@ class RouteTable(Module):
         return Network(srvdb)
         
     def prepare(self):
-        if not config.record and is_network_prepared():
+        if not config.record and net_is_prepared():
             return
         self.info()
         for net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi in self.db.get_route_tbl():
@@ -1394,10 +1522,10 @@ class RouteTable(Module):
                 lctl.connect(srv)
 
     def safe_to_clean(self):
-        return not is_network_prepared()
+        return not net_is_prepared()
 
     def cleanup(self):
-        if is_network_prepared():
+        if net_is_prepared():
             # the network is still being used, don't clean it up
             return
         for net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi in self.db.get_route_tbl():
@@ -1417,14 +1545,44 @@ class RouteTable(Module):
                 e.dump()
                 cleanup_error(e.rc)
 
+class Management(Module):
+    def __init__(self, db):
+        Module.__init__(self, 'MGMT', db)
+
+    def add_module(self, manager):
+        manager.add_lustre_module('lvfs', 'lvfs')
+        manager.add_lustre_module('obdclass', 'obdclass')
+        manager.add_lustre_module('ptlrpc', 'ptlrpc')
+        manager.add_lustre_module('mgmt', 'mgmt_svc')
+
+    def prepare(self):
+        if not config.record and is_prepared(self.name):
+            return
+        self.info()
+        lctl.newdev("mgmt", self.name, self.uuid)
+
+    def safe_to_clean(self):
+        return 1
+
+    def cleanup(self):
+        if is_prepared(self.name):
+            Module.cleanup(self)
+
+    def correct_level(self, level, op=None):
+        return level
+
 # This is only needed to load the modules; the LDLM device
 # is now created automatically.
 class LDLM(Module):
     def __init__(self,db):
         Module.__init__(self, 'LDLM', db)
-        self.add_lustre_module('lvfs', 'lvfs')
-        self.add_lustre_module('obdclass', 'obdclass')
-        self.add_lustre_module('ptlrpc', 'ptlrpc')
+
+    def add_module(self, manager):
+        manager.add_lustre_module('lvfs', 'lvfs')
+        manager.add_lustre_module('obdclass', 'obdclass')
+        manager.add_lustre_module('sec', 'ptlrpcs')
+        manager.add_lustre_module('ptlrpc', 'ptlrpc')
+       manager.add_lustre_module('sec/gss', 'ptlrpcs_gss')
 
     def prepare(self):
         return
@@ -1435,13 +1593,11 @@ class LDLM(Module):
     def correct_level(self, level, op=None):
         return level
 
-
 class LOV(Module):
     def __init__(self, db, uuid, fs_name, name_override = None, config_only = None):
         Module.__init__(self, 'LOV', db)
         if name_override != None:
             self.name = "lov_%s" % name_override
-        self.add_lustre_module('lov', 'lov')
         self.mds_uuid = self.db.get_first_ref('mds')
         self.stripe_sz = self.db.get_val_int('stripesize', 1048576)
         self.stripe_off = self.db.get_val_int('stripeoffset', 0)
@@ -1503,22 +1659,13 @@ class LOV(Module):
         if self.config_only:
             panic("Can't clean up config_only LOV ", self.name)
 
-    def load_module(self):
+    def add_module(self, manager):
         if self.config_only:
             panic("Can't load modules for config_only LOV ", self.name)
         for (osc, index, gen, active) in self.osclist:
-            osc.load_module()
-            break
-        Module.load_module(self)
-
-    def cleanup_module(self):
-        if self.config_only:
-            panic("Can't cleanup modules for config_only LOV ", self.name)
-        Module.cleanup_module(self)
-        for (osc, index, gen, active) in self.osclist:
-            if active:
-                osc.cleanup_module()
+            osc.add_module(manager)
             break
+        manager.add_lustre_module('lov', 'lov')
 
     def correct_level(self, level, op=None):
         return level
@@ -1528,8 +1675,11 @@ class LMV(Module):
         Module.__init__(self, 'LMV', db)
         if name_override != None:
             self.name = "lmv_%s" % name_override
-        self.add_lustre_module('lmv', 'lmv')
-        self.devlist = self.db.get_refs('mds')
+           
+        self.devlist = self.db.get_lmv_tgts('lmv_tgt')
+       if self.devlist == None:
+           self.devlist = self.db.get_refs('mds')
+           
         self.mdclist = []
         self.desc_uuid = self.uuid
         self.uuid = uuid
@@ -1547,6 +1697,8 @@ class LMV(Module):
     def prepare(self):
         if is_prepared(self.name):
             return
+           
+       self.info();
         for mdc in self.mdclist:
             try:
                 # Only ignore connect failures with --force, which
@@ -1555,6 +1707,7 @@ class LMV(Module):
             except CommandError, e:
                 print "Error preparing LMV %s\n" % mdc.uuid
                 raise e
+       
         lctl.lmv_setup(self.name, self.uuid, self.desc_uuid,
                        string.join(self.devlist))
 
@@ -1564,341 +1717,265 @@ class LMV(Module):
         if is_prepared(self.name):
             Module.cleanup(self)
 
-    def load_module(self):
-        for mdc in self.mdclist:
-            mdc.load_module()
-            break
-        Module.load_module(self)
-
-    def cleanup_module(self):
-        Module.cleanup_module(self)
+    def add_module(self, manager):
         for mdc in self.mdclist:
-            mdc.cleanup_module()
+            mdc.add_module(manager)
             break
+        manager.add_lustre_module('lmv', 'lmv')
 
     def correct_level(self, level, op=None):
         return level
 
-class MDSDEV(Module):
-    def __init__(self,db):
-        Module.__init__(self, 'MDSDEV', db)
+class CONFDEV(Module):
+    def __init__(self, db, name, target_uuid, uuid):
+        Module.__init__(self, 'CONFDEV', db)
         self.devpath = self.db.get_val('devpath','')
-        self.backdevpath = self.db.get_val('backdevpath','')
+        self.backdevpath = self.db.get_val('devpath','')
         self.size = self.db.get_val_int('devsize', 0)
         self.journal_size = self.db.get_val_int('journalsize', 0)
         self.fstype = self.db.get_val('fstype', '')
         self.backfstype = self.db.get_val('backfstype', '')
-        self.nspath = self.db.get_val('nspath', '')
         self.mkfsoptions = self.db.get_val('mkfsoptions', '')
         self.mountfsoptions = self.db.get_val('mountfsoptions', '')
-        self.root_squash = self.db.get_val('root_squash', '')
-        self.no_root_squash = self.db.get_val('no_root_squash', '')
-        self.cachetype = self.db.get_val('cachetype', '')
-       # overwrite the orignal MDSDEV name and uuid with the MDS name and uuid
-        target_uuid = self.db.get_first_ref('target')
-        mds = self.db.lookup(target_uuid)
-        self.name = mds.getName()
-        self.filesystem_uuids = mds.get_refs('filesystem')
-       self.lmv_uuid = ''
-       self.lmv = ''
-        self.master_mds = ""
-       if not self.filesystem_uuids:
-           self.lmv_uuid = self.db.get_first_ref('lmv')
-           if not self.lmv_uuid:
-               panic("ALERT: can't find lvm uuid")
-           if self.lmv_uuid:
-               self.lmv = self.db.lookup(self.lmv_uuid)
-               if self.lmv:
-                   self.filesystem_uuids = self.lmv.get_refs('filesystem')
-                    self.master_mds = self.lmv_uuid
-        # FIXME: if fstype not set, then determine based on kernel version
-        self.format = self.db.get_val('autoformat', "no")
-        if mds.get_val('failover', 0):
-            self.failover_mds = 'f'
-        else:
-            self.failover_mds = 'n'
-        active_uuid = get_active_target(mds)
-        if not active_uuid:
-            panic("No target device found:", target_uuid)
-        if active_uuid == self.uuid:
-            self.active = 1
-        else:
-            self.active = 0
-        if self.active and config.group and config.group != mds.get_val('group'):
-            self.active = 0
-
-        self.inode_size = self.db.get_val_int('inodesize', 0)
-        if self.inode_size == 0:
-            # find the LOV for this MDS
-            lovconfig_uuid = mds.get_first_ref('lovconfig')
-            if not lovconfig_uuid:
-                if not self.lmv_uuid:
-                    panic("No LOV found for lovconfig ", lovconfig.name)
-
-               if not self.lmv:
-                   panic("No LMV initialized and not lovconfig_uuid found")
-               
-                lovconfig_uuid = self.lmv.get_first_ref('lovconfig')
-                lovconfig = self.lmv.lookup(lovconfig_uuid)
-                lov_uuid = lovconfig.get_first_ref('lov')
-                if not lov_uuid:
-                    panic("No LOV found for lovconfig ", lovconfig.name)
-           else:
-                lovconfig = mds.lookup(lovconfig_uuid)
-                lov_uuid = lovconfig.get_first_ref('lov')
-                if not lov_uuid:
-                    panic("No LOV found for lovconfig ", lovconfig.name)
-
-               if self.lmv:
-                   lovconfig_uuid = self.lmv.get_first_ref('lovconfig')
-                   lovconfig = self.lmv.lookup(lovconfig_uuid)
-                   lov_uuid = lovconfig.get_first_ref('lov')
-
-            lov = LOV(self.db.lookup(lov_uuid), lov_uuid, 'FS_name', config_only = 1)
-
-            # default stripe count controls default inode_size
-            if (lov.stripe_cnt > 0):
-                stripe_count = lov.stripe_cnt
-            else:
-                stripe_count = len(lov.devlist)
-            if stripe_count > 77:
-                self.inode_size = 4096
-            elif stripe_count > 35:
-                self.inode_size = 2048
-            elif stripe_count > 13:
-                self.inode_size = 1024
-            elif stripe_count > 3:
-                self.inode_size = 512
+       self.target = self.db.lookup(target_uuid)
+        self.name = "conf_%s" % self.target.getName()
+        self.client_uuids = self.target.get_refs('client')
+        self.obdtype = self.db.get_val('obdtype', '')
+       
+        self.mds_sec = self.db.get_val('mds_sec', '')
+        self.oss_sec = self.db.get_val('oss_sec', '')
+        self.deny_sec = self.db.get_val('deny_sec', '')
+
+        if config.mds_mds_sec:
+            self.mds_sec = config.mds_mds_sec
+        if config.mds_oss_sec:
+            self.oss_sec = config.mds_oss_sec
+        if config.mds_deny_sec:
+            if self.deny_sec:
+                self.deny_sec = "%s,%s" %(self.deny_sec, config.mds_deny_sec)
             else:
-                self.inode_size = 256
+                self.deny_sec = config.mds_deny_sec
 
-        self.target_dev_uuid = self.uuid
-        self.uuid = target_uuid
-       # setup LMV
-       if self.master_mds:
-            client_uuid = generate_client_uuid(self.name)
-           client_uuid = self.name + "_lmv_" + "UUID"
-           self.master = LMV(self.db.lookup(self.lmv_uuid), client_uuid, self.name, self.name)
-           self.master_mds = self.master.name
-
-        # modules
-        self.add_lustre_module('mdc', 'mdc')
-        self.add_lustre_module('osc', 'osc')
-        self.add_lustre_module('lov', 'lov')
-        self.add_lustre_module('lmv', 'lmv')
-        self.add_lustre_module('ost', 'ost')
-        self.add_lustre_module('mds', 'mds')
-
-        if self.fstype == 'smfs':
-            self.add_lustre_module('smfs', 'smfs')
-
-        if self.fstype == 'ldiskfs':
-            self.add_lustre_module('ldiskfs', 'ldiskfs')
-
-        if self.fstype:
-            self.add_lustre_module('lvfs', 'fsfilt_%s' % (self.fstype))
-
-        # if fstype is smfs, then we should also take care about backing
-        # store fs.
-        if self.fstype == 'smfs':
-            self.add_lustre_module('lvfs', 'fsfilt_%s' % (self.backfstype))
-
-       for options in string.split(self.mountfsoptions, ','):
-           if options == 'snap':
-               if not self.fstype == 'smfs':
-                   panic("mountoptions with snap, but fstype is not smfs\n")
-               self.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.fstype))
-               self.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.backfstype))
-    def load_module(self):
-        if self.active:
-            Module.load_module(self)
+        if self.obdtype == None:
+            self.obdtype = 'dumb'
+       
+        self.conf_name = name
+        self.conf_uuid = uuid
+        self.realdev = self.devpath
+       
+       self.lmv = None
+        self.master = None
+       
+        lmv_uuid = self.db.get_first_ref('lmv')
+       if lmv_uuid != None:
+           self.lmv = self.db.lookup(lmv_uuid)
+           if self.lmv != None:
+                self.client_uuids = self.lmv.get_refs('client')
+
+        if self.target.get_class() == 'mds':
+           if self.target.get_val('failover', 0):
+               self.failover_mds = 'f'
+           else:
+               self.failover_mds = 'n'
+            self.format = self.db.get_val('autoformat', "no")
+        else:
+            self.format = self.db.get_val('autoformat', "yes")
+            self.osdtype = self.db.get_val('osdtype')
+            ost = self.db.lookup(target_uuid)
+            if ost.get_val('failover', 0):
+                self.failover_ost = 'f'
+            else:
+                self.failover_ost = 'n'
 
-    def prepare(self):
-        if not config.record and is_prepared(self.name):
-            return
-        if not self.active:
-            debug(self.uuid, "not active")
-            return
-        if config.reformat:
-            # run write_conf automatically, if --reformat used
-            self.write_conf()
-        self.info(self.devpath, self.fstype, self.size, self.format)
-        run_acceptors()
-       # prepare LMV
-       if self.master_mds:
-             self.master.prepare()
-        # never reformat here
-        blkdev = block_dev(self.devpath, self.size, self.fstype, 0,
-                           self.format, self.journal_size, self.inode_size,
-                           self.mkfsoptions, self.backfstype, self.backdevpath)
+       self.inode_size = self.get_inode_size()
 
-        if not is_prepared('MDT'):
-            lctl.newdev("mdt", 'MDT', 'MDT_UUID', setup ="")
-        try:
-            mountfsoptions = def_mount_options(self.fstype, 'mds')
+       if self.lmv != None:
+           client_uuid = self.name + "_lmv_UUID"
+           self.master = LMV(self.lmv, client_uuid, 
+                             self.conf_name, self.conf_name)
 
-            if config.mountfsoptions:
-                if mountfsoptions:
-                    mountfsoptions = mountfsoptions + ',' + config.mountfsoptions
+    def get_inode_size(self):
+        inode_size = self.db.get_val_int('inodesize', 0)
+        if inode_size == 0 and self.target.get_class() == 'mds':
+       
+           # default inode size for case when neither LOV either 
+           # LMV is accessible.
+           self.inode_size = 256
+           
+            # find the LOV for this MDS
+            lovconfig_uuid = self.target.get_first_ref('lovconfig')
+            if lovconfig_uuid or self.lmv != None:
+                if self.lmv != None:
+                    lovconfig_uuid = self.lmv.get_first_ref('lovconfig')
+                    lovconfig = self.lmv.lookup(lovconfig_uuid)
+                    lov_uuid = lovconfig.get_first_ref('lov')
+                    if lov_uuid == None:
+                        panic(self.target.getName() + ": No LOV found for lovconfig ", 
+                              lovconfig.name)
+               else:
+                    lovconfig = self.target.lookup(lovconfig_uuid)
+                    lov_uuid = lovconfig.get_first_ref('lov')
+                    if lov_uuid == None:
+                       panic(self.target.getName() + ": No LOV found for lovconfig ", 
+                             lovconfig.name)
+                   if self.lmv != None:
+                       lovconfig_uuid = self.lmv.get_first_ref('lovconfig')
+                       lovconfig = self.lmv.lookup(lovconfig_uuid)
+                       lov_uuid = lovconfig.get_first_ref('lov')
+
+                lov = LOV(self.db.lookup(lov_uuid), lov_uuid, self.name, 
+                          config_only = 1)
+
+                # default stripe count controls default inode_size
+               if lov.stripe_cnt > 0:
+                   stripe_count = lov.stripe_cnt
+               else:
+                   stripe_count = len(lov.devlist)
+                if stripe_count > 77:
+                    inode_size = 4096
+                elif stripe_count > 35:
+                    inode_size = 2048
+                elif stripe_count > 13:
+                    inode_size = 1024
+                elif stripe_count > 3:
+                    inode_size = 512
                 else:
-                    mountfsoptions = config.mountfsoptions
-                if self.mountfsoptions:
-                    mountfsoptions = mountfsoptions + ',' + self.mountfsoptions
+                    inode_size = 256
+                   
+       return inode_size
+           
+    def get_mount_options(self, blkdev):
+        options = def_mount_options(self.fstype, 
+                                   self.target.get_class())
+            
+        if config.mountfsoptions:
+            if options:
+                options = "%s,%s" %(options, config.mountfsoptions)
             else:
-                if self.mountfsoptions:
-                    if mountfsoptions:
-                        mountfsoptions = mountfsoptions + ',' + self.mountfsoptions
-                    else:
-                        mountfsoptions = self.mountfsoptions
-
-            if self.fstype == 'smfs':
-                realdev = self.fstype
-
-                if mountfsoptions:
-                    mountfsoptions = "%s,type=%s,dev=%s" % (mountfsoptions,
-                                                            self.backfstype,
-                                                            blkdev)
+                options = config.mountfsoptions
+            if self.mountfsoptions:
+                options = "%s,%s" %(options, self.mountfsoptions)
+        else:
+            if self.mountfsoptions:
+                if options:
+                    options = "%s,%s" %(options, self.mountfsoptions)
                 else:
-                    mountfsoptions = "type=%s,dev=%s" % (self.backfstype,
-                                                         blkdev)
+                    options = self.mountfsoptions
+            
+        if self.fstype == 'smfs':
+            if options:
+                options = "%s,type=%s,dev=%s" %(options, self.backfstype, 
+                                               blkdev)
             else:
-                realdev = blkdev
-
-            print 'MDS mount options: ' + mountfsoptions
-
-           if not self.master_mds:
-                self.master_mds = 'dumb'       
-            if not self.cachetype:
-                self.cachetype = 'dumb'
-           lctl.newdev("mds", self.name, self.uuid,
-                        setup ="%s %s %s %s %s %s" %(realdev, self.fstype,
-                                               self.name, mountfsoptions,
-                                               self.master_mds, self.cachetype))
-
-            if development_mode():
-                procentry = "/proc/fs/lustre/mds/grp_hash_upcall"
-                upcall = os.path.abspath(os.path.dirname(sys.argv[0]) + "/l_getgroups")
-                if not (os.access(procentry, os.R_OK) and os.access(upcall, os.R_OK)):
-                    print "MDS Warning: failed to set group-hash upcall"
-                else:
-                    run("echo ", upcall, " > ", procentry)
+                options = "type=%s,dev=%s" %(self.backfstype, 
+                                            blkdev)
+        
+       if self.target.get_class() == 'mds':
+           if options:
+               options = "%s,acl,user_xattr,iopen_nopriv" %(options)
+           else:
+               options = "iopen_nopriv"
+           
+       return options
 
-        except CommandError, e:
-            if e.rc == 2:
-                panic("MDS is missing the config log. Need to run " +
-                       "lconf --write_conf.")
-            else:
-                raise e
+    def prepare(self):
+        if is_prepared(self.name):
+            return
         
-       if config.root_squash == None:
-            config.root_squash = self.root_squash
-        if config.no_root_squash == None:
-            config.no_root_squash = self.no_root_squash
-        if config.root_squash:
-            if config.no_root_squash:
-                nsnid = config.no_root_squash
-            else:
-                nsnid = "0"
-            lctl.root_squash(self.name, config.root_squash, nsnid)
+        blkdev = block_dev(self.devpath, self.size, self.fstype,
+                           config.reformat, self.format, self.journal_size,
+                           self.inode_size, self.mkfsoptions, self.backfstype,
+                           self.backdevpath)
 
-    def write_conf(self):
-        do_cleanup = 0
-        if not is_prepared(self.name):
-            self.info(self.devpath, self.fstype, self.format)
+        if self.fstype == 'smfs':
+            realdev = blkdev
+        else:
+            realdev = blkdev
+               
+       mountfsoptions = self.get_mount_options(blkdev)
 
-            blkdev = block_dev(self.devpath, self.size, self.fstype,
-                               config.reformat, self.format, self.journal_size,
-                               self.inode_size, self.mkfsoptions,
-                               self.backfstype, self.backdevpath)
+       self.info(self.target.get_class(), realdev, mountfsoptions, 
+                 self.fstype, self.size, self.format)
 
-            # Even for writing logs we mount mds with supplied mount options
-            # because it will not mount smfs (if used) otherwise.
+        lctl.newdev("confobd", self.name, self.uuid, 
+                   setup ="%s %s %s" %(realdev, self.fstype, 
+                                       mountfsoptions))
 
-            mountfsoptions = def_mount_options(self.fstype, 'mds')
+        self.mountfsoptions = mountfsoptions
+        self.realdev = realdev
 
-            if config.mountfsoptions:
-                if mountfsoptions:
-                    mountfsoptions = mountfsoptions + ',' + config.mountfsoptions
-                else:
-                    mountfsoptions = config.mountfsoptions
-                if self.mountfsoptions:
-                    mountfsoptions = mountfsoptions + ',' + self.mountfsoptions
-            else:
-                if self.mountfsoptions:
-                    if mountfsoptions:
-                        mountfsoptions = mountfsoptions + ',' + self.mountfsoptions
-                    else:
-                        mountfsoptions = self.mountfsoptions
+    def add_module(self, manager):
+       manager.add_lustre_module('obdclass', 'confobd')
 
-            if self.fstype == 'smfs':
-                realdev = self.fstype
+    def write_conf(self):
+        if self.target.get_class() == 'ost':
+            config.record = 1
+            lctl.clear_log(self.name, self.target.getName() + '-conf')
+            lctl.record(self.name, self.target.getName() + '-conf')
+            lctl.newdev(self.osdtype, self.conf_name, self.conf_uuid,
+                        setup ="%s %s %s %s" %(self.realdev, self.fstype,
+                                               self.failover_ost,
+                                               self.mountfsoptions))
+            lctl.end_record()
+            lctl.clear_log(self.name, 'OSS-conf')
+            lctl.record(self.name, 'OSS-conf')
+            lctl.newdev("ost", 'OSS', 'OSS_UUID', setup ="")
+            lctl.end_record()
+            config.record = 0
+            return
+
+        if self.target.get_class() == 'mds':
+           if self.master != None:
+               master_name = self.master.name
+           else:
+               master_name = 'dumb'
+
+           config.record = 1
+            lctl.clear_log(self.name, self.target.getName() + '-conf')
+            lctl.record(self.name, self.target.getName() + '-conf')
+            lctl.attach("mds", self.conf_name, self.conf_uuid)
+            if self.mds_sec:
+                lctl.set_security(self.conf_name, "mds_sec", self.mds_sec)
+            if self.oss_sec:
+                lctl.set_security(self.conf_name, "oss_sec", self.oss_sec)
+            if self.deny_sec:
+                for flavor in string.split(self.deny_sec, ','):
+                    lctl.set_security(self.conf_name, "deny_sec", flavor)
+            lctl.newdev("mds", self.conf_name, self.conf_uuid,
+                        setup ="%s %s %s %s %s %s" %(self.realdev, self.fstype,
+                                                    self.conf_name, self.mountfsoptions,
+                                                    master_name, self.obdtype))
+            lctl.end_record()
+            config.record = 0
 
-                if mountfsoptions:
-                    mountfsoptions = "%s,type=%s,dev=%s" % (mountfsoptions,
-                                                            self.backfstype,
-                                                            blkdev)
-                else:
-                    mountfsoptions = "type=%s,dev=%s" % (self.backfstype,
-                                                         blkdev)
-            else:
-                realdev = blkdev
-       
-                print 'MDS mount options: ' + mountfsoptions
-
-            # As mount options are passed by 4th param to config tool, we need
-            # to pass something in 3rd param. But we do not want this 3rd param
-            # be counted as a profile name for reading log on MDS setup, thus,
-            # we pass there some predefined sign like 'dumb', which will be
-            # checked in MDS code and skipped. Probably there is more nice way
-            # like pass empty string and check it in config tool and pass null
-            # as 4th param.
-            lctl.newdev("mds", self.name, self.uuid,
-                        setup ="%s %s %s %s" %(realdev, self.fstype,
-                                               'dumb', mountfsoptions))
-            do_cleanup = 1
-
-        # record logs for the MDS lov
-        for uuid in self.filesystem_uuids:
-            log("recording clients for filesystem:", uuid)
-            fs = self.db.lookup(uuid)
-
-            # this is ugly, should be organized nice later.
-            target_uuid = self.db.get_first_ref('target')
-            mds = self.db.lookup(target_uuid)
-
-            lovconfig_uuid = mds.get_first_ref('lovconfig')
-            if lovconfig_uuid:
-                lovconfig = mds.lookup(lovconfig_uuid)
-                obd_uuid = lovconfig.get_first_ref('lov')
-            else:
-                obd_uuid = fs.get_first_ref('obd')
+        if not self.client_uuids:
+            return 0
 
+        for uuid in self.client_uuids:
+            log("recording client:", uuid)
             client_uuid = generate_client_uuid(self.name)
-            client = VOSC(self.db.lookup(obd_uuid), client_uuid, self.name,
-                          self.name)
+            client = VOSC(self.db.lookup(uuid), client_uuid, 
+                         self.target.getName(), self.name)
             config.record = 1
-            lctl.clear_log(self.name, self.name)
-            lctl.record(self.name, self.name)
+            lctl.clear_log(self.name, self.target.getName())
+            lctl.record(self.name, self.target.getName())
             client.prepare()
-            lctl.mount_option(self.name, client.get_name(), "")
+            lctl.mount_option(self.target.getName(), client.get_name(), "")
             lctl.end_record()
-            process_updates(self.db, self.name, self.name, client)
 
             config.cleanup = 1
-            lctl.clear_log(self.name, self.name + '-clean')
-            lctl.record(self.name, self.name + '-clean')
+            lctl.clear_log(self.name, self.target.getName() + '-clean')
+            lctl.record(self.name, self.target.getName() + '-clean')
             client.cleanup()
-            lctl.del_mount_option(self.name)
+            lctl.del_mount_option(self.target.getName())
             lctl.end_record()
-            process_updates(self.db, self.name, self.name + '-clean', client)
             config.cleanup = 0
             config.record = 0
 
+        if config.record:
+            return
+
         # record logs for each client
-        if config.noexec:
-            noexec_opt = '-n'
-        else:
-            noexec_opt = ''
         if config.ldapurl:
             config_options = "--ldapurl " + config.ldapurl + " --config " + config.config
         else:
@@ -1915,7 +1992,9 @@ class MDSDEV(Module):
                         debug("recording", client_name)
                         old_noexec = config.noexec
                         config.noexec = 0
-                        ret, out = run (sys.argv[0], noexec_opt,
+                        noexec_opt = ('', '-n')
+                        ret, out = run (sys.argv[0],
+                                        noexec_opt[old_noexec == 1],
                                         " -v --record --nomod",
                                         "--record_log", client_name,
                                         "--record_device", self.name,
@@ -1923,7 +2002,8 @@ class MDSDEV(Module):
                                         config_options)
                         if config.verbose:
                             for s in out: log("record> ", string.strip(s))
-                        ret, out = run (sys.argv[0], noexec_opt,
+                        ret, out = run (sys.argv[0],
+                                        noexec_opt[old_noexec == 1],
                                         "--cleanup -v --record --nomod",
                                         "--record_log", client_name + "-clean",
                                         "--record_device", self.name,
@@ -1932,19 +2012,165 @@ class MDSDEV(Module):
                         if config.verbose:
                             for s in out: log("record> ", string.strip(s))
                         config.noexec = old_noexec
-        if do_cleanup:
+
+    def start(self):
+         try:
+            lctl.start(self.name, self.conf_name)
+         except CommandError, e:
+            raise e
+         if self.target.get_class() == 'ost':
+             if not is_prepared('OSS'):
+                 try:
+                     lctl.start(self.name, 'OSS')
+                 except CommandError, e:
+                     raise e
+
+    def cleanup(self):
+        if is_prepared(self.name):
             try:
                 lctl.cleanup(self.name, self.uuid, 0, 0)
+               clean_dev(self.devpath, self.fstype, 
+                         self.backfstype, self.backdevpath)
             except CommandError, e:
                 log(self.module_name, "cleanup failed: ", self.name)
                 e.dump()
                 cleanup_error(e.rc)
                 Module.cleanup(self)
-        
+
+class MDSDEV(Module):
+    def __init__(self,db):
+        Module.__init__(self, 'MDSDEV', db)
+        self.devpath = self.db.get_val('devpath','')
+        self.backdevpath = self.db.get_val('devpath','')
+        self.size = self.db.get_val_int('devsize', 0)
+        self.journal_size = self.db.get_val_int('journalsize', 0)
+        self.fstype = self.db.get_val('fstype', '')
+        self.backfstype = self.db.get_val('backfstype', '')
+        self.nspath = self.db.get_val('nspath', '')
+        self.mkfsoptions = self.db.get_val('mkfsoptions', '')
+        self.mountfsoptions = self.db.get_val('mountfsoptions', '')
+        self.obdtype = self.db.get_val('obdtype', '')
+        self.root_squash = self.db.get_val('root_squash', '')
+        self.no_root_squash = self.db.get_val('no_root_squash', '')
+
+        target_uuid = self.db.get_first_ref('target')
+        self.target = self.db.lookup(target_uuid)
+        self.name = self.target.getName()
+        self.master = None
+       self.lmv = None
+       
+        lmv_uuid = self.db.get_first_ref('lmv')
+       if lmv_uuid != None:
+           self.lmv = self.db.lookup(lmv_uuid)
+
+        active_uuid = get_active_target(self.target)
+        if not active_uuid:
+            panic("No target device found:", target_uuid)
+        if active_uuid == self.uuid:
+            self.active = 1
+           group = self.target.get_val('group')
+           if config.group and config.group != group:
+               self.active = 0
+        else:
+            self.active = 0
+
+        self.uuid = target_uuid
+
+       # setup LMV
+       if self.lmv != None:
+           client_uuid = self.name + "_lmv_UUID"
+           self.master = LMV(self.lmv, client_uuid, 
+                             self.name, self.name)
+                             
+        self.confobd = CONFDEV(self.db, self.name, 
+                              target_uuid, self.uuid)
+
+    def add_module(self, manager):
+        if self.active:
+            manager.add_lustre_module('mdc', 'mdc')
+            manager.add_lustre_module('osc', 'osc')
+            manager.add_lustre_module('ost', 'ost')
+            manager.add_lustre_module('lov', 'lov')
+            manager.add_lustre_module('mds', 'mds')
+
+            if self.fstype == 'smfs' or self.fstype == 'ldiskfs':
+                manager.add_lustre_module(self.fstype, self.fstype)
+               
+            if self.fstype:
+                manager.add_lustre_module('lvfs', 'fsfilt_%s' % (self.fstype))
+            
+            # if fstype is smfs, then we should also take care about backing 
+            # store fs.
             if self.fstype == 'smfs':
-                clean_loop(self.backdevpath)
+                manager.add_lustre_module(self.backfstype, self.backfstype)
+                manager.add_lustre_module('lvfs', 'fsfilt_%s' % (self.backfstype))
+
+           for option in string.split(self.mountfsoptions, ','):
+               if option == 'snap':
+                   if not self.fstype == 'smfs':
+                       panic("mountoptions has 'snap', but fstype is not smfs.")
+                   manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.fstype))
+                   manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.backfstype))
+
+       # add LMV modules
+       if self.master != None:
+            self.master.add_module(manager)
+       # add CONFOBD modules
+       if self.confobd != None:
+            self.confobd.add_module(manager)
+           
+    def write_conf(self):
+        if is_prepared(self.name):
+            return
+        if not self.active:
+            debug(self.uuid, "not active")
+            return
+        run_acceptors()
+        self.confobd.prepare()
+        self.confobd.write_conf()
+        self.confobd.cleanup()
+
+    def prepare(self):
+        if is_prepared(self.name):
+            return
+        if not self.active:
+            debug(self.uuid, "not active")
+            return
+        run_acceptors()
+
+        self.confobd.prepare()
+        if config.reformat:
+            self.confobd.write_conf()
+
+       # prepare LMV
+       if self.master != None:
+             self.master.prepare()
+
+       if not config.record:
+            self.confobd.start()
+       
+       if not is_prepared('MDT'):
+           lctl.newdev("mdt", 'MDT', 'MDT_UUID', setup ="")
+
+        if development_mode():
+            procentry = "/proc/fs/lustre/mds/lsd_upcall"
+            upcall = os.path.abspath(os.path.dirname(sys.argv[0]) + "/lsd_upcall")
+            if not (os.access(procentry, os.R_OK) and os.access(upcall, os.R_OK)):
+                print "MDS Warning: failed to set lsd cache upcall"
+            else:
+                run("echo ", upcall, " > ", procentry)
+
+       if config.root_squash == None:
+            config.root_squash = self.root_squash
+        if config.no_root_squash == None:
+            config.no_root_squash = self.no_root_squash
+        if config.root_squash:
+            if config.no_root_squash:
+                nsnid = config.no_root_squash
             else:
-                clean_loop(self.devpath)
+                nsnid = "0"
+            lctl.root_squash(self.name, config.root_squash, nsnid)
 
     def msd_remaining(self):
         out = lctl.device_list()
@@ -1957,7 +2183,7 @@ class MDSDEV(Module):
 
     def safe_to_clean_modules(self):
         return not self.msd_remaining()
-
+        
     def cleanup(self):
         if not self.active:
             debug(self.uuid, "not active")
@@ -1973,7 +2199,7 @@ class MDSDEV(Module):
                 cleanup_error(e.rc)
                 Module.cleanup(self)
            # cleanup LMV
-           if self.master_mds:
+           if self.master != None:
                 self.master.cleanup()
         if not self.msd_remaining() and is_prepared('MDT'):
             try:
@@ -1983,23 +2209,21 @@ class MDSDEV(Module):
                 print "cleanup failed: ", self.name
                 e.dump()
                 cleanup_error(e.rc)
-
-        if self.fstype == 'smfs':
-            clean_loop(self.backdevpath)
-        else:
-            clean_loop(self.devpath)
+        
+        if self.confobd:
+            self.confobd.cleanup()
 
     def correct_level(self, level, op=None):
-       #if self.master_mds:
+       #if self.master != None:
        #   level = level + 2
         return level
-
+       
 class OSD(Module):
     def __init__(self, db):
         Module.__init__(self, 'OSD', db)
         self.osdtype = self.db.get_val('osdtype')
         self.devpath = self.db.get_val('devpath', '')
-        self.backdevpath = self.db.get_val('backdevpath', '')
+        self.backdevpath = self.db.get_val('devpath', '')
         self.size = self.db.get_val_int('devsize', 0)
         self.journal_size = self.db.get_val_int('journalsize', 0)
         self.inode_size = self.db.get_val_int('inodesize', 0)
@@ -2017,100 +2241,96 @@ class OSD(Module):
         else:
             self.failover_ost = 'n'
 
+        self.deny_sec = self.db.get_val('deny_sec', '')
+
+        if config.ost_deny_sec:
+            if self.deny_sec:
+                self.deny_sec = "%s,%s" %(self.deny_sec, config.ost_deny_sec)
+            else:
+                self.deny_sec = config.ost_deny_sec
+
         active_uuid = get_active_target(ost)
         if not active_uuid:
             panic("No target device found:", target_uuid)
         if active_uuid == self.uuid:
             self.active = 1
+           group = ost.get_val('group')
+           if config.group and config.group != group:
+               self.active = 0
         else:
             self.active = 0
-        if self.active and config.group and config.group != ost.get_val('group'):
-            self.active = 0
-            
-        self.target_dev_uuid = self.uuid
+
         self.uuid = target_uuid
-        # modules
-        self.add_lustre_module('ost', 'ost')
-        if self.fstype == 'smfs':
-            self.add_lustre_module('smfs', 'smfs')
-        # FIXME: should we default to ext3 here?
-        if self.fstype == 'ldiskfs':
-            self.add_lustre_module('ldiskfs', 'ldiskfs')
+        self.confobd = CONFDEV(self.db, self.name, 
+                              target_uuid, self.uuid)
+
+    def add_module(self, manager):
+        if not self.active:
+           return
+        manager.add_lustre_module('ost', 'ost')
+            
+        if self.fstype == 'smfs' or self.fstype == 'ldiskfs':
+            manager.add_lustre_module(self.fstype, self.fstype)
+               
         if self.fstype:
-            self.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.fstype))
+            manager.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.fstype))
+
         if self.fstype == 'smfs':
-            self.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.backfstype))
+            manager.add_lustre_module(self.backfstype, self.backfstype)
+            manager.add_lustre_module('lvfs' , 'fsfilt_%s' % (self.backfstype))
 
-       for options in self.mountfsoptions:
-           if options == 'snap':
+       for option in self.mountfsoptions:
+           if option == 'snap':
                if not self.fstype == 'smfs':
                    panic("mountoptions with snap, but fstype is not smfs\n")
-               self.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.fstype))
-               self.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.backfstype))
+               manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.fstype))
+               manager.add_lustre_module('lvfs', 'fsfilt_snap_%s' % (self.backfstype))
 
-        self.add_lustre_module(self.osdtype, self.osdtype)
-
-    def load_module(self):
-        if self.active:
-            Module.load_module(self)
+        manager.add_lustre_module(self.osdtype, self.osdtype)
+       
+       # add CONFOBD modules
+       if self.confobd != None:
+            self.confobd.add_module(manager)
 
-    # need to check /proc/mounts and /etc/mtab before
-    # formatting anything.
-    # FIXME: check if device is already formatted.
     def prepare(self):
         if is_prepared(self.name):
             return
         if not self.active:
             debug(self.uuid, "not active")
             return
-        self.info(self.osdtype, self.devpath, self.size, self.fstype,
-                  self.format, self.journal_size, self.inode_size)
-        run_acceptors()
-        if self.osdtype == 'obdecho':
-            blkdev = ''
-        else:
-            blkdev = block_dev(self.devpath, self.size, self.fstype,
-                               config.reformat, self.format, self.journal_size,
-                               self.inode_size, self.mkfsoptions, self.backfstype,
-                               self.backdevpath)
-
-        mountfsoptions = def_mount_options(self.fstype, 'ost')
-
-        if config.mountfsoptions:
-            if mountfsoptions:
-                mountfsoptions = mountfsoptions + ',' + config.mountfsoptions
-            else:
-                mountfsoptions = config.mountfsoptions
-            if self.mountfsoptions:
-                mountfsoptions = mountfsoptions + ',' + self.mountfsoptions
-        else:
-            if self.mountfsoptions:
-                if mountfsoptions:
-                    mountfsoptions = mountfsoptions + ',' + self.mountfsoptions
-                else:
-                    mountfsoptions = self.mountfsoptions
 
-        if self.fstype == 'smfs':
-            realdev = self.fstype
+        run_acceptors()
 
-            if mountfsoptions:
-                mountfsoptions = "%s,type=%s,dev=%s" % (mountfsoptions,
-                                                        self.backfstype,
-                                                        blkdev)
-            else:
-                mountfsoptions = "type=%s,dev=%s" % (self.backfstype,
-                                                     blkdev)
-        else:
-            realdev = blkdev
+        if self.osdtype == 'obdecho':
+            self.info(self.osdtype)
+            lctl.newdev("obdecho", self.name, self.uuid)
+            if not is_prepared('OSS'):
+                lctl.newdev("ost", 'OSS', 'OSS_UUID', setup="")
+       else:
+           self.confobd.prepare()
+           if config.reformat:
+               self.confobd.write_conf()
+           if not config.record:
+               self.confobd.start()        
 
-        print 'OSD mount options: ' + mountfsoptions
+        if self.deny_sec:
+            for flavor in string.split(self.deny_sec, ','):
+                lctl.set_security(self.name, "deny_sec", flavor)
 
-        lctl.newdev(self.osdtype, self.name, self.uuid,
-                    setup ="%s %s %s %s" %(realdev, self.fstype,
-                                           self.failover_ost,
-                                           mountfsoptions))
-        if not is_prepared('OSS'):
-            lctl.newdev("ost", 'OSS', 'OSS_UUID', setup ="")
+    def write_conf(self):
+        if is_prepared(self.name):
+            return
+        if not self.active:
+            debug(self.uuid, "not active")
+            return
+                                                                                                               
+        run_acceptors()
+        if self.osdtype != 'obdecho':
+           self.confobd.prepare()
+           self.confobd.write_conf()
+           if not config.write_conf:
+               self.confobd.start()
+           self.confobd.cleanup()
 
     def osd_remaining(self):
         out = lctl.device_list()
@@ -2128,6 +2348,7 @@ class OSD(Module):
         if not self.active:
             debug(self.uuid, "not active")
             return
+           
         if is_prepared(self.name):
             self.info()
             try:
@@ -2145,30 +2366,29 @@ class OSD(Module):
                 print "cleanup failed: ", self.name
                 e.dump()
                 cleanup_error(e.rc)
-        if not self.osdtype == 'obdecho':
-            if self.fstype == 'smfs':
-                clean_loop(self.backdevpath)
-            else:
-                clean_loop(self.devpath)
+
+        if self.osdtype != 'obdecho':
+            if self.confobd:
+                self.confobd.cleanup()
 
     def correct_level(self, level, op=None):
         return level
 
 # Generic client module, used by OSC and MDC
 class Client(Module):
-    def __init__(self, tgtdb, uuid, module, fs_name, self_name=None,
-                 module_dir=None):
+    def __init__(self, tgtdb, uuid, module, fs_name, 
+                self_name=None, module_dir=None):
         self.target_name = tgtdb.getName()
         self.target_uuid = tgtdb.getUUID()
+        self.module_dir = module_dir
+        self.backup_targets = []
+       self.module = module
         self.db = tgtdb
-        self.active = 1
-       self.backup_targets = []
 
-       self.tgt_dev_uuid = get_active_target(tgtdb)
+        self.tgt_dev_uuid = get_active_target(tgtdb)
         if not self.tgt_dev_uuid:
             panic("No target device found for target(1):", self.target_name)
 
-        self.kmod = kmod(config.lustre, config.portals)
         self._server = None
         self._connected = 0
 
@@ -2181,22 +2401,26 @@ class Client(Module):
             self.name = self_name
         self.uuid = uuid
         self.lookup_server(self.tgt_dev_uuid)
-       
-       self.lookup_backup_targets()
+        self.lookup_backup_targets()
         self.fs_name = fs_name
-        if not module_dir:
-            module_dir = module
-        self.add_lustre_module(module_dir, module)
+        if not self.module_dir:
+            self.module_dir = module
+
+    def add_module(self, manager):
+        manager.add_lustre_module(self.module_dir, self.module)
 
     def lookup_server(self, srv_uuid):
         """ Lookup a server's network information """
         self._server_nets = get_ost_net(self.db, srv_uuid)
         if len(self._server_nets) == 0:
             panic ("Unable to find a server for:", srv_uuid)
+           
     def get_name(self):
         return self.name
+
     def get_servers(self):
         return self._server_nets
+
     def lookup_backup_targets(self):
         """ Lookup alternative network information """
         prof_list = toplustreDB.get_refs('profile')
@@ -2228,8 +2452,9 @@ class Client(Module):
         except CommandError, e:
             if not ignore_connect_failure:
                 raise e
+
         if srv:
-            if self.permits_inactive() and (self.target_uuid in config.inactive or self.active == 0):
+            if self.target_uuid in config.inactive and self.permits_inactive():
                 debug("%s inactive" % self.target_uuid)
                 inactive_p = "inactive"
             else:
@@ -2278,7 +2503,6 @@ class Client(Module):
                     for (srv, r) in find_route(this_net):
                         lctl.del_route_host(r[0]. srv.nid_uuid, r[1], r[3])
 
-
     def correct_level(self, level, op=None):
         return level
 
@@ -2304,173 +2528,162 @@ class OSC(Client):
     def permits_inactive(self):
         return 1
 
-class VLOV(Module):
-    def __init__(self, db, uuid, fs_name, name_override = None, config_only = None):
-        Module.__init__(self, 'VLOV', db)
-        if name_override != None:
-            self.name = "lov_%s" % name_override
-        self.add_lustre_module('lov', 'lov')
-        self.stripe_sz = 65536
-        self.stripe_off = 0
-        self.pattern =  0
-        self.stripe_cnt = 1
-        self.desc_uuid = self.uuid
-        self.uuid = generate_client_uuid(self.name)
-        self.fs_name = fs_name
-        self.osc = get_osc(db, self.uuid, fs_name)
-        if not self.osc:
-           panic('osc not found:', self.uuid)
-       if config_only:
-            self.config_only = 1
-            return
-        self.config_only = None
-    def get_uuid(self):
-        return self.uuid
-    def get_name(self):
-        return self.name
-    def prepare(self):
-        if not config.record and is_prepared(self.name):
-            return
-        lctl.lov_setup(self.name, self.uuid, self.desc_uuid, self.stripe_cnt,
-                       self.stripe_sz, self.stripe_off, self.pattern)
-        target_uuid = self.osc.target_uuid
-        try:
-           self.osc.active = 1
-            self.osc.prepare(ignore_connect_failure=0)
-        except CommandError, e:
-            print "Error preparing OSC %s\n" % osc.uuid
-            raise e
-        lctl.lov_add_obd(self.name, self.uuid, target_uuid, 0, 1)
-
-    def cleanup(self):
-        target_uuid = self.osc.target_uuid
-        self.osc.cleanup()
-        if is_prepared(self.name):
-            Module.cleanup(self)
-        if self.config_only:
-            panic("Can't clean up config_only LOV ", self.name)
-
-    def load_module(self):
-        if self.config_only:
-            panic("Can't load modules for config_only LOV ", self.name)
-        self.osc.load_module()
-        Module.load_module(self)
-
-    def cleanup_module(self):
-        if self.config_only:
-            panic("Can't cleanup modules for config_only LOV ", self.name)
-        Module.cleanup_module(self)
-        self.osc.cleanup_module()
-
-    def correct_level(self, level, op=None):
-        return level
-
 class CMOBD(Module):
-    def __init__(self,db):
+    def __init__(self, db):
        Module.__init__(self, 'CMOBD', db)
-       self.name = self.db.getName();
+       self.name = self.db.getName(); 
        self.uuid = generate_client_uuid(self.name)
        self.master_uuid = self.db.get_first_ref('masterobd')
        self.cache_uuid = self.db.get_first_ref('cacheobd')
-       self.add_lustre_module('cmobd', 'cmobd')
+
        master_obd = self.db.lookup(self.master_uuid)
        if not master_obd:
            panic('master obd not found:', self.master_uuid)
+
        cache_obd = self.db.lookup(self.cache_uuid)
        if not cache_obd:
            panic('cache obd not found:', self.cache_uuid)
-       
-       if master_obd.get_class() == 'ost':
-           self.client_uuid = generate_client_uuid(self.name)
-           self.master= VLOV(master_obd, self.client_uuid, self.name,
-                           "%s_master" % (self.name))
-           self.master_uuid = self.master.get_uuid()
+           
+       self.master = None
+       self.cache = None
+            
+        master_class = master_obd.get_class()
+        cache_class = cache_obd.get_class()
+
+       if master_class == 'ost' or master_class == 'lov':
+           client_uuid = "%s_lov_master_UUID" % (self.name)
+            self.master = LOV(master_obd, client_uuid, self.name);
+        elif master_class == 'mds':
+           self.master = get_mdc(db, self.name, self.master_uuid) 
+        elif master_class == 'lmv':
+           #tmp fix: cobd and cmobd will use same uuid, so use const name here
+           client_uuid = "%s_lmv_master_UUID" % "master" 
+            self.master = LMV(master_obd, client_uuid, self.name);
+       else:
+           panic("unknown master obd class '%s'" %(master_class))
+           
+       if cache_class == 'ost' or cache_class == 'lov':
+           client_uuid = "%s_lov_cache_UUID" % (self.name)
+            self.cache = LOV(cache_obd, client_uuid, self.name);
+        elif cache_class == 'mds':
+           self.cache = get_mdc(db, self.name, self.cache_uuid)
+        elif cache_class == 'lmv':
+           client_uuid = "%s_lmv_cache_UUID" % (self.name) 
+            self.cache = LMV(cache_obd, client_uuid, self.name);
        else:
-           self.master = get_mdc(db, self.name, self.master_uuid)
-    # need to check /proc/mounts and /etc/mtab before
-    # formatting anything.
-    # FIXME: check if device is already formatted.
+           panic("unknown cache obd class '%s'" %(cache_class))
+
     def prepare(self):
         self.master.prepare()
         if not config.record and is_prepared(self.name):
             return
         self.info(self.master_uuid, self.cache_uuid)
         lctl.newdev("cmobd", self.name, self.uuid,
-                    setup ="%s %s" %(self.master_uuid,
-                                     self.cache_uuid))
+                    setup ="%s %s" %(self.master.uuid,
+                                     self.cache.uuid))
+
+    def get_uuid(self):
+        return self.uuid
+       
+    def get_name(self):
+        return self.name
+       
+    def get_master_name(self):
+       return self.master.name
+           
+    def get_cache_name(self):
+        return self.cache.name
 
     def cleanup(self):
         if is_prepared(self.name):
             Module.cleanup(self)
-        self.master.cleanup()
-
-    def load_module(self):
-        self.master.load_module()
-        Module.load_module(self)
+       if self.master:
+           self.master.cleanup()
 
-    def cleanup_module(self):
-        Module.cleanup_module(self)
-        self.master.cleanup_module()
+    def add_module(self, manager):
+       manager.add_lustre_module('smfs', 'smfs')
+       manager.add_lustre_module('cmobd', 'cmobd')
+        self.master.add_module(manager)
 
     def correct_level(self, level, op=None):
         return level
 
 class COBD(Module):
-    def __init__(self, db, uuid, name, type, name_override = None):
+    def __init__(self, db, uuid, name):
         Module.__init__(self, 'COBD', db)
-        self.name = self.db.getName();
+        self.name = self.db.getName(); 
         self.uuid = generate_client_uuid(self.name)
-        self.real_uuid = self.db.get_first_ref('realobd')
+        self.master_uuid = self.db.get_first_ref('masterobd')
         self.cache_uuid = self.db.get_first_ref('cacheobd')
-        self.add_lustre_module('cobd', 'cobd')
-        real_obd = self.db.lookup(self.real_uuid)
-        if not real_obd:
-            panic('real obd not found:', self.real_uuid)
+
+        master_obd = self.db.lookup(self.master_uuid)
+        if not master_obd:
+            panic('master obd not found:', self.master_uuid)
+
         cache_obd = self.db.lookup(self.cache_uuid)
         if not cache_obd:
             panic('cache obd not found:', self.cache_uuid)
-        if type == 'obd':
-            self.real = LOV(real_obd, self.real_uuid, name,
-                            "%s_real" % (self.name));
-            self.cache = LOV(cache_obd, self.cache_uuid, name,
-                            "%s_cache" % (self.name));
-        else:
-            self.real = get_mdc(db,  name, self.real_uuid)
+           
+       self.master = None
+       self.cache = None
+
+        master_class = master_obd.get_class()
+        cache_class = cache_obd.get_class()
+
+       if master_class == 'ost' or master_class == 'lov':
+           client_uuid = "%s_lov_master_UUID" % (self.name)
+            self.master = LOV(master_obd, client_uuid, name);
+        elif master_class == 'mds':
+            self.master = get_mdc(db, name, self.master_uuid) 
+        elif master_class == 'lmv':
+           #tmp fix: cobd and cmobd will use same uuid, so use const name here
+           client_uuid = "%s_lmv_master_UUID" % "master" 
+            self.master = LMV(master_obd, client_uuid, self.name);
+       else:
+           panic("unknown master obd class '%s'" %(master_class))
+           
+       if cache_class == 'ost' or cache_class == 'lov':
+           client_uuid = "%s_lov_cache_UUID" % (self.name)
+            self.cache = LOV(cache_obd, client_uuid, name);
+        elif cache_class == 'mds':
             self.cache = get_mdc(db, name, self.cache_uuid)
-    # need to check /proc/mounts and /etc/mtab before
-    # formatting anything.
-    # FIXME: check if device is already formatted.
+        elif cache_class == 'lmv':
+           client_uuid = "%s_lmv_cache_UUID" % "cache" 
+            self.cache = LMV(cache_obd, client_uuid, self.name);
+       else:
+           panic("unknown cache obd class '%s'" %(cache_class))
+           
     def get_uuid(self):
         return self.uuid
+
     def get_name(self):
         return self.name
-    def get_real_name(self):
-        return self.real.name
+
+    def get_master_name(self):
+        return self.master.name
+
     def get_cache_name(self):
         return self.cache.name
+
     def prepare(self):
-        self.real.prepare()
-        self.cache.prepare()
         if not config.record and is_prepared(self.name):
             return
-        self.info(self.real_uuid, self.cache_uuid)
+       self.master.prepare()
+        self.cache.prepare()
+        self.info(self.master_uuid, self.cache_uuid)
         lctl.newdev("cobd", self.name, self.uuid,
-                    setup ="%s %s" %(self.real.name,
+                    setup ="%s %s" %(self.master.name,
                                      self.cache.name))
 
     def cleanup(self):
         if is_prepared(self.name):
             Module.cleanup(self)
-        self.real.cleanup()
+        self.master.cleanup()
         self.cache.cleanup()
 
-    def load_module(self):
-        self.real.load_module()
-        Module.load_module(self)
-
-    def cleanup_module(self):
-        Module.cleanup_module(self)
-        self.real.cleanup_module()
+    def add_module(self, manager):
+        manager.add_lustre_module('cobd', 'cobd')
+        self.master.add_module(manager)
 
 # virtual interface for  OSC and LOV
 class VOSC(Module):
@@ -2480,23 +2693,27 @@ class VOSC(Module):
             self.osc = LOV(db, client_uuid, name, name_override)
             self.type = 'lov'
         elif db.get_class() == 'cobd':
-            self.osc = COBD(db, client_uuid, name, 'obd')
+            self.osc = COBD(db, client_uuid, name)
             self.type = 'cobd'
         else:
             self.osc = OSC(db, client_uuid, name)
             self.type = 'osc'
+           
     def get_uuid(self):
         return self.osc.get_uuid()
+
     def get_name(self):
         return self.osc.get_name()
+
     def prepare(self):
         self.osc.prepare()
+       
     def cleanup(self):
         self.osc.cleanup()
-    def load_module(self):
-        self.osc.load_module()
-    def cleanup_module(self):
-        self.osc.cleanup_module()
+       
+    def add_module(self, manager):
+        self.osc.add_module(manager)
+       
     def correct_level(self, level, op=None):
         return self.osc.correct_level(level, op)
 
@@ -2505,30 +2722,33 @@ class VMDC(Module):
     def __init__(self, db, client_uuid, name, name_override = None):
         Module.__init__(self, 'VMDC', db)
         if db.get_class() == 'lmv':
-            self.mdc = LMV(db, client_uuid, name)
+            self.mdc = LMV(db, client_uuid, name, name_override)
         elif db.get_class() == 'cobd':
-            self.mdc = COBD(db, client_uuid, name, 'mds')
+            self.mdc = COBD(db, client_uuid, name)
         else:
             self.mdc = MDC(db, client_uuid, name)
+           
     def get_uuid(self):
         return self.mdc.uuid
+
     def get_name(self):
         return self.mdc.name
+
     def prepare(self):
         self.mdc.prepare()
+       
     def cleanup(self):
         self.mdc.cleanup()
-    def load_module(self):
-        self.mdc.load_module()
-    def cleanup_module(self):
-        self.mdc.cleanup_module()
+       
+    def add_module(self, manager):
+        self.mdc.add_module(manager)
+       
     def correct_level(self, level, op=None):
         return self.mdc.correct_level(level, op)
 
 class ECHO_CLIENT(Module):
     def __init__(self,db):
         Module.__init__(self, 'ECHO_CLIENT', db)
-        self.add_lustre_module('obdecho', 'obdecho')
         self.obd_uuid = self.db.get_first_ref('obd')
         obd = self.db.lookup(self.obd_uuid)
         self.uuid = generate_client_uuid(self.name)
@@ -2549,13 +2769,9 @@ class ECHO_CLIENT(Module):
             Module.cleanup(self)
         self.osc.cleanup()
 
-    def load_module(self):
-        self.osc.load_module()
-        Module.load_module(self)
-
-    def cleanup_module(self):
-        Module.cleanup_module(self)
-        self.osc.cleanup_module()
+    def add_module(self, manager):
+        self.osc.add_module(manager)
+        manager.add_lustre_module('obdecho', 'obdecho')
 
     def correct_level(self, level, op=None):
         return level
@@ -2567,29 +2783,11 @@ def generate_client_uuid(name):
                                                int(random.random() * 1048576))
         return client_uuid[:36]
 
-def my_rstrip(s, chars):
-    """my_rstrip(s, chars) -> strips any instances of the characters
-    found in chars from the right side of string s"""
-    # XXX required because python versions pre 2.2.3 don't allow
-    #string.rstrip() to take alternate char lists
-    import string
-    ns=s
-    try:
-        ns = string.rstrip(s, '/')
-    except TypeError, e:
-        for i in range(len(s) - 1, 0, -1):
-            if s[i] in chars:
-                continue
-            else:
-                ns = s[0:i+1]
-                break
-    return ns
-
 class Mountpoint(Module):
     def __init__(self,db):
         Module.__init__(self, 'MTPT', db)
         self.path = self.db.get_val('path')
-       self.clientoptions = self.db.get_val('clientoptions', '')
+        self.clientoptions = self.db.get_val('clientoptions', '')
         self.fs_uuid = self.db.get_first_ref('filesystem')
         fs = self.db.lookup(self.fs_uuid)
         self.mds_uuid = fs.get_first_ref('lmv')
@@ -2598,55 +2796,57 @@ class Mountpoint(Module):
         self.obd_uuid = fs.get_first_ref('obd')
         client_uuid = generate_client_uuid(self.name)
 
+        self.oss_sec = self.db.get_val('oss_sec','null')
+        self.mds_sec = self.db.get_val('mds_sec','null')
+        if config.mds_sec:
+            self.mds_sec = config.mds_sec
+        if config.oss_sec:
+            self.oss_sec = config.oss_sec
+
         ost = self.db.lookup(self.obd_uuid)
         if not ost:
             panic("no ost: ", self.obd_uuid)
-
+            
         mds = self.db.lookup(self.mds_uuid)
        if not mds:
            panic("no mds: ", self.mds_uuid)
-
-        self.add_lustre_module('mdc', 'mdc')
-        self.add_lustre_module('lmv', 'lmv')
-        self.add_lustre_module('llite', 'llite')
-
-        self.vosc = VOSC(ost, client_uuid, self.name)
-       self.vmdc = VMDC(mds, client_uuid, self.name)
-
+       
+        self.vosc = VOSC(ost, client_uuid, self.name, self.name)
+       self.vmdc = VMDC(mds, client_uuid, self.name, self.name)
+        
     def prepare(self):
         if not config.record and fs_is_mounted(self.path):
             log(self.path, "already mounted.")
             return
         run_acceptors()
-        self.vosc.prepare()
+
+       self.vosc.prepare()
         self.vmdc.prepare()
-        vmdc_name = self.vmdc.get_name()
 
         self.info(self.path, self.mds_uuid, self.obd_uuid)
         if config.record or config.lctl_dump:
-            lctl.mount_option(local_node_name, self.vosc.get_name(), vmdc_name)
+            lctl.mount_option(local_node_name, self.vosc.get_name(), 
+                             self.vmdc.get_name())
             return
 
         if config.clientoptions:
             if self.clientoptions:
-                self.clientoptions = self.clientoptions + ',' + \
-                                    config.clientoptions
+                self.clientoptions = self.clientoptions + ',' + config.clientoptions
             else:
                 self.clientoptions = config.clientoptions
         if self.clientoptions:
             self.clientoptions = ',' + self.clientoptions
             # Linux kernel will deal with async and not pass it to ll_fill_super,
             # so replace it with Lustre async
-            self.clientoptions = string.replace(self.clientoptions, "async",
-                                               "lasync")
+            self.clientoptions = string.replace(self.clientoptions, "async", "lasync")
 
-        cmd = "mount -t lustre_lite -o osc=%s,mdc=%s%s %s %s" % \
-              (self.vosc.get_name(), vmdc_name, self.clientoptions,
-              config.config, self.path)
+        cmd = "mount -t lustre_lite -o osc=%s,mdc=%s,mds_sec=%s,oss_sec=%s%s %s %s" % \
+              (self.vosc.get_name(), self.vmdc.get_name(), self.mds_sec,
+              self.oss_sec, self.clientoptions, config.config, self.path)
         run("mkdir", self.path)
         ret, val = run(cmd)
         if ret:
-            self.vmdc.cleanup()
+            self.vmdc.cleanup()            
             self.vosc.cleanup()
             panic("mount failed:", self.path, ":", string.join(val))
 
@@ -2670,13 +2870,10 @@ class Mountpoint(Module):
         self.vmdc.cleanup()
         self.vosc.cleanup()
 
-    def load_module(self):
-        self.vosc.load_module()
-        Module.load_module(self)
-
-    def cleanup_module(self):
-        Module.cleanup_module(self)
-        self.vosc.cleanup_module()
+    def add_module(self, manager):
+        self.vosc.add_module(manager)
+        self.vmdc.add_module(manager)
+        manager.add_lustre_module('llite', 'llite')
 
     def correct_level(self, level, op=None):
         return level
@@ -2699,7 +2896,6 @@ def get_ost_net(self, osd_uuid):
         srv_list.append(Network(db))
     return srv_list
 
-
 # the order of iniitailization is based on level. 
 def getServiceLevel(self):
     type = self.get_class()
@@ -2716,10 +2912,10 @@ def getServiceLevel(self):
         ret = 40
     elif type in ('lmv',):
         ret = 45
-    elif type in ('cmobd',):
-        ret = 50
     elif type in ('mountpoint', 'echoclient'):
-        ret = 70
+        ret = 60
+    elif type in ('cmobd',):
+        ret = 70 
     else:
         panic("Unknown type: ", type)
 
@@ -2776,9 +2972,8 @@ def find_local_clusters(node_db):
         debug("add_local", netuuid)
         local_clusters.append((srv.net_type, srv.cluster_id, srv.nid))
         if srv.port > 0:
-            if acceptors.has_key(srv.port):
-                panic("duplicate port:", srv.port)
-            acceptors[srv.port] = AcceptorHandler(srv.port, srv.net_type)
+            if not acceptors.has_key(srv.port):
+                acceptors[srv.port] = AcceptorHandler(srv.port, srv.net_type)
 
 # This node is a gateway.
 is_router = 0
@@ -3059,9 +3254,10 @@ def doWriteconf(services):
     #if config.nosetup:
     #    return
     for s in services:
-        if s[1].get_class() == 'mdsdev':
+        if s[1].get_class() == 'mdsdev' or s[1].get_class() == 'osd':
             n = newService(s[1])
             n.write_conf()
+            n.cleanup()
 
 def doSetup(services):
     if config.nosetup:
@@ -3079,17 +3275,36 @@ def doSetup(services):
     for n in nlist:
         n[1].prepare()
 
-def doModules(services):
+def doLoadModules(services):
+    if config.nomod:
+        return
+       
+    # adding all needed modules from all services
+    for s in services:
+        n = newService(s[1])
+        n.add_module(mod_manager)
+    
+    # loading all registered modules
+    mod_manager.load_modules()
+
+def doUnloadModules(services):
     if config.nomod:
         return
+        
+    # adding all needed modules from all services
     for s in services:
         n = newService(s[1])
-        n.load_module()
+        if n.safe_to_clean_modules():
+            n.add_module(mod_manager)
+    
+    # unloading all registered modules
+    mod_manager.cleanup_modules()
 
 def doCleanup(services):
     if config.nosetup:
         return
     slist = []
+
     for s in services:
         n = newService(s[1])
        n.level = s[0]
@@ -3100,19 +3315,11 @@ def doCleanup(services):
        nlist.append((nl, n[1]))
     nlist.sort()
     nlist.reverse()
+
     for n in nlist:
         if n[1].safe_to_clean():
             n[1].cleanup()
 
-def doUnloadModules(services):
-    if config.nomod:
-        return
-    services.reverse()
-    for s in services:
-        n = newService(s[1])
-        if n.safe_to_clean_modules():
-            n.cleanup_module()
-
 #
 # Load profile for 
 def doHost(lustreDB, hosts):
@@ -3142,7 +3349,7 @@ def doHost(lustreDB, hosts):
     prof_list = node_db.get_refs('profile')
 
     if config.write_conf:
-        for_each_profile(node_db, prof_list, doModules)
+        for_each_profile(node_db, prof_list, doLoadModules)
         sys_make_devices()
         for_each_profile(node_db, prof_list, doWriteconf)
         for_each_profile(node_db, prof_list, doUnloadModules)
@@ -3185,7 +3392,7 @@ def doHost(lustreDB, hosts):
         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)
+        for_each_profile(node_db, prof_list, doLoadModules)
 
         sys_set_debug_path()
         sys_set_ptldebug(ptldebug)
@@ -3329,7 +3536,7 @@ def sys_set_ptldebug(ptldebug):
     if ptldebug:
         try:
             val = eval(ptldebug, ptldebug_names)
-            val = "0x%x" % (val)
+            val = "0x%x" % (val & 0xffffffffL)
             sysctl('portals/debug', val)
         except NameError, e:
             panic(str(e))
@@ -3340,7 +3547,7 @@ def sys_set_subsystem(subsystem):
     if subsystem:
         try:
             val = eval(subsystem, subsystem_names)
-            val = "0x%x" % (val)
+            val = "0x%x" % (val & 0xffffffffL)
             sysctl('portals/subsystem_debug', val)
         except NameError, e:
             panic(str(e))
@@ -3358,14 +3565,12 @@ def sys_set_netmem_max(path, max):
         fp.write('%d\n' %(max))
         fp.close()
     
-    
 def sys_make_devices():
     if not os.access('/dev/portals', os.R_OK):
         run('mknod /dev/portals c 10 240')
     if not os.access('/dev/obd', os.R_OK):
         run('mknod /dev/obd c 10 241')
 
-
 # Add dir to the global PATH, if not already there.
 def add_to_path(new_dir):
     syspath = string.split(os.environ['PATH'], ':')
@@ -3387,7 +3592,6 @@ def default_gdb_script():
     else:
         return script
 
-
 DEFAULT_PATH = ('/sbin', '/usr/sbin', '/bin', '/usr/bin')
 # ensure basic elements are in the system path
 def sanitise_path():
@@ -3421,6 +3625,13 @@ lconf_options = [
     ('config', "Cluster config name used for LDAP query", PARAM),
     ('select', "service=nodeA,service2=nodeB ", PARAMLIST),
     ('node',   "Load config for <nodename>", PARAM),
+    ('sec',"security flavor <null|krb5i|krb5p> between this client with mds", PARAM),
+    ('mds_sec',"security flavor <null|krb5i|krb5p> between this client with mds", PARAM),
+    ('oss_sec',"security flavor <null|krb5i|krb5p> between this client with ost", PARAM),
+    ('mds_mds_sec',"security flavor <null|krb5i|krb5p> between this mds with other mds", PARAM),
+    ('mds_oss_sec',"security flavor <null|krb5i|krb5p> between this mds with ost", PARAM),
+    ('mds_deny_sec', "security flavor <null|krb5i|krb5p> denied by this mds", PARAM),
+    ('ost_deny_sec', "security flavor <null|krb5i|krb5p> denied by this ost", PARAM),
     ('cleanup,d', "Cleans up config. (Shutdown)"),
     ('force,f', "Forced unmounting and/or obd detach during cleanup",
                FLAG, 0),
@@ -3489,7 +3700,7 @@ lconf_options = [
     ]      
 
 def main():
-    global lctl, config, toplustreDB, CONFIG_FILE
+    global lctl, config, toplustreDB, CONFIG_FILE, mod_manager
 
     # in the upcall this is set to SIG_IGN
     signal.signal(signal.SIGCHLD, signal.SIG_DFL)
@@ -3596,6 +3807,9 @@ def main():
         lctl.clear_log(config.record_device, config.record_log)
         lctl.record(config.record_device, config.record_log)
 
+    # init module manager
+    mod_manager = kmod_manager(config.lustre, config.portals)
+
     doHost(lustreDB, node_list)
 
     if not config.record: