Whamcloud - gitweb
* Compiles after merging b1_4
[fs/lustre-release.git] / lustre / utils / lconf
index 33a19b6..408bb76 100755 (executable)
@@ -37,7 +37,7 @@ if sys.version[0] == '1':
 else:
     from fcntl import F_GETFL, F_SETFL
 
-PYMOD_DIR = ["/usr/lib/lustre/python", "/usr/lib64/lustre/python"]
+PYMOD_DIR = ["/usr/lib64/lustre/python", "/usr/lib/lustre/python"]
 
 def development_mode():
     base = os.path.dirname(sys.argv[0])
@@ -153,8 +153,10 @@ def logall(msgs):
         print string.strip(s)
 
 def debug(*args):
+    # apparently, (non)execution of the following line affects mds device
+    # startup order (e.g. two mds's using loopback devices), so always do it.
+    msg = string.join(map(str,args))
     if config.verbose:
-        msg = string.join(map(str,args))
         print msg
 
 # ack, python's builtin int() does not support '0x123' syntax.
@@ -290,6 +292,8 @@ class AcceptorHandler(DaemonHandler):
         self.port = port
         self.net_type = net_type
         self.flags = ''
+        if config.allow_unprivileged_port:
+            self.flags = '-p'
 
     def pidfile(self):
         return "/var/run/%s-%d.pid" % (self.command, self.port)
@@ -483,7 +487,7 @@ class LCTLInterface:
 
     def add_peer(self, net_type, nid, hostaddr, port):
         """ noop """
-#         if net_type  in ('tcp','openib','ra') and not config.lctl_dump:
+#         if net_type  in ('tcp','openib','ra','cray_kern_nal') and not config.lctl_dump:
 #             cmds =  """
 #   network %s
 #   add_peer %s %s %d
@@ -507,10 +511,49 @@ class LCTLInterface:
 
     def connect(self, srv):
         self.add_uuid(srv.net_type, srv.nid_uuid, srv.nid)
-#         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)
+#        if config.lctl_dump:
+#            return
+#
+#        if srv.net_type  in ('tcp',):
+#            host = socket.gethostname()
+#            node_list = []
+#            if config.node:
+#                node_list.append(config.node)
+#            else:
+#                if len(host) > 0:
+#                    node_list.append(host)
+#                node_list.append('localhost')
+#
+#            node_db = None
+#            for h in node_list: # we are quite sure we can find the node_db
+#                node_db = toplustreDB.lookup_name(h, 'node')
+#                if node_db:
+#                    break
+#
+#            hostaddr = None
+#            for netuuid in node_db.get_networks():
+#                localnet = toplustreDB.lookup(netuuid)
+#                localnet = Network(localnet)
+#                if localnet.net_type != 'tcp':
+#                    continue  # only tcp understands multiple hostaddrs
+#
+#                # always true for tcp network
+#                if localnet.hostaddr[0] and srv.hostaddr[0]:
+#                    for lnet in localnet.hostaddr:
+#                        for pnet in srv.hostaddr:
+#                            if srv.netmatch(lnet, pnet) != 0:
+#                                hostaddr = string.split(pnet, '/')[0]
+#                                #find one is enough, should break the top-most loop
+#                                break
+#                        if hostaddr: break
+#                    else:     # can't find a match
+#                        hostaddr = string.split(srv.hostaddr[0], '/')[0]
+#                    break
+#
+#            self.add_peer(srv.net_type, srv.nid, hostaddr, srv.port)
+#            
+#        if srv.net_type in ('openib','iib','vib','ra'):
+#            self.add_peer(srv.net_type, srv.nid, srv.hostaddr[0], srv.port)
 
     # Recover a device
     def recover(self, dev_name, new_conn):
@@ -629,7 +672,7 @@ class LCTLInterface:
     def abort_recovery(self, name):
         cmds = """
   ignore_errors
-  device %s
+  device $%s
   abort_recovery
   quit""" % (name)
         self.run(cmds)
@@ -918,7 +961,7 @@ def mkfs(dev, devsize, fstype, jsize, isize, mkfsoptions, isblock=1):
         panic("Unable to build fs:", dev, string.join(out))
     # enable hash tree indexing on fsswe
     if fstype in ('ext3', 'extN', 'ldiskfs'):
-        htree = 'echo "feature FEATURE_C5" | debugfs -w'
+        htree = 'tune2fs -O dir_index'
         (ret, out) = run (htree, dev)
         if ret:
             panic("Unable to enable htree:", dev)
@@ -933,7 +976,7 @@ def loop_base():
             loop='/dev/loop'
     return loop
 
-# find loop device assigned to thefile
+# find loop device assigned to the file
 def find_loop(file):
     loop = loop_base()
     for n in xrange(0, MAX_LOOP_DEVICES):
@@ -1045,15 +1088,17 @@ def sys_get_local_nid(net_type, wildcard, cluster_id):
     # don't need a real nid for config log - client will replace (bug5619)
     if config.record:
         local = "54321"
-    elif net_type in ('tcp','openib','iib','vib','ra'):
+    elif net_type in ('tcp','openib','iib','vib','ra','cray_kern_nal'):
         if  ':' in wildcard:
             iface, star = string.split(wildcard, ':')
             local = if2addr(iface)
-            if not local:
-                panic("unable to determine ip for:", wildcard)
+        elif net_type == 'vib':
+            local = if2addr('ipoib0')
         else:
             host = socket.gethostname()
             local = socket.gethostbyname(host)
+        if not local:
+            panic("unable to determine ip for:", wildcard)
     elif net_type == 'elan':
         # awk '/NodeId/ { print $2 }' 'sys_get_elan_position_file()'
         f = sys_get_elan_position_file()
@@ -1093,18 +1138,7 @@ def sys_get_local_nid(net_type, wildcard, cluster_id):
 
 def sys_get_branch():
     """Returns kernel release"""
-    try:
-        fp = open('/proc/sys/kernel/osrelease')
-        lines = fp.readlines()
-        fp.close()
-
-        for l in lines:
-            version = string.split(l)
-            a = string.split(version[0], '.')
-            return a[0] + '.' + a[1]
-    except IOError, e:
-        log(e)
-    return ""
+    return os.uname()[2][:3]
 
 def mod_loaded(modname):
     """Check if a module is already loaded. Look in /proc/modules for it."""
@@ -1397,6 +1431,65 @@ class Network(Module):
                 ip = string.split(hostaddr, '/')[0]
                 lctl.del_interface(self.net_type, ip)
 
+    def my_inet_aton(self, net):
+        split = net.split('.')
+        if len(split) != 4:
+            raise ValueError, "Invalid IPv4 address %s" % net
+
+        naddr = 0
+        i = 0
+        for n in split:
+            try:
+                naddr = naddr + int(n) * (256 ** (3-i))
+            except:
+                raise ValueError, "Invalid IPv4 address %s" % net
+            i = i + 1
+        return naddr
+
+    def tointAddr(self, net):
+        """convert a net address/mask into (numeric-address, bitmap-mask)"""
+        try:
+            addr, mask = string.split(net, '/')
+        except:
+            addr = net
+            mask = 24 #eeb told me that kernel uses this value by default
+
+        try:
+            mask = int(mask)
+            assert(mask >= 1 and mask <= 32)
+            mask = bitmap_32(mask)
+        except:
+            try:
+                mask = self.my_inet_aton(mask)
+            except:
+                raise ValueError("Invalid netmask %s" % str(mask))
+
+        try:
+            addr = socket.gethostbyname(addr)
+            naddr = self.my_inet_aton(addr)
+        except:
+            raise ValueError("Invalid host %s" % addr)
+
+        return (naddr, mask)
+
+    def netmatch(self, net1, net2):
+        # XXX this is only valid for IPv4 address
+        try:
+            addr1, mask1 = self.tointAddr(net1)
+            addr2, mask2 = self.tointAddr(net2)
+        except:
+            return 0
+
+        if addr1 & mask1 == addr2 & mask2:
+            return 1
+        return 0
+
+def bitmap_32(n):
+    """n should be in [1, 32]"""
+    if n < 0 or n > 32:
+        raise ValueError("A number between 1 and 32 is expected. (not %d)" % n)
+    return (-1) << (32-n)
+
 class RouteTable(Module):
     def __init__(self,db):
         Module.__init__(self, 'ROUTES', db)
@@ -1507,11 +1600,12 @@ class LOV(Module):
         self.stripe_off = self.db.get_val_int('stripeoffset', 0)
         self.pattern = self.db.get_val_int('stripepattern', 0)
         self.devlist = []
-        self.stripe_cnt = 0
+        self.stripe_cnt = self.db.get_val_int('stripecount', 1)
         self.osclist = []
         self.desc_uuid = self.uuid
         self.uuid = generate_client_uuid(self.name)
         self.fs_name = fs_name
+        # settings below here won't be seen by the MDSDEV code!
         if config_only:
             self.config_only = 1
             return
@@ -1542,7 +1636,7 @@ class LOV(Module):
                 index = index + 1
         if self.osclist == []:
             panic('No OSCs configured for LOV')
-        self.stripe_cnt = self.db.get_val_int('stripecount', len(self.devlist))
+        debug('dbg LOV __init__:', self.osclist, self.devlist, self.stripe_cnt)
 
     def prepare(self):
         debug('dbg LOV prepare')
@@ -1570,13 +1664,10 @@ class LOV(Module):
             lctl.lov_add_obd(self.name, self.uuid, target_uuid, index, gen)
 
     def cleanup(self):
-        for (osc, index, gen, active) in self.osclist:
-            target_uuid = osc.target_uuid
-            if is_prepared(osc.name):
-                lctl.lov_del_obd(self.name, self.uuid, target_uuid, index, gen)
-            osc.cleanup()
         if is_prepared(self.name):
             Module.cleanup(self)
+        for (osc, index, gen, active) in self.osclist:
+            osc.cleanup()
         if self.config_only:
             panic("Can't clean up config_only LOV ", self.name)
 
@@ -1603,7 +1694,13 @@ class MDSDEV(Module):
         self.devpath = 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', '')
+        if sys_get_branch() == '2.4' and self.fstype == 'ldiskfs':
+            self.fstype = 'ext3'
+        elif sys_get_branch() == '2.6' and self.fstype == 'ext3':
+            self.fstype = 'ldiskfs'
+
         self.nspath = self.db.get_val('nspath', '')
         self.mkfsoptions = '-i 4096 ' + self.db.get_val('mkfsoptions', '')
         self.mountfsoptions = self.db.get_val('mountfsoptions', '')
@@ -1625,7 +1722,7 @@ class MDSDEV(Module):
             self.active = 1
         else:
             self.active = 0
-        if self.active and config.group and config.group != mds.get_val('group'):
+        if self.active and config.group and config.group != mds.get_val('group', mds.get_val('name')):
             self.active = 0
 
         self.inode_size = self.db.get_val_int('inodesize', 0)
@@ -1644,17 +1741,19 @@ class MDSDEV(Module):
             if (lov.stripe_cnt > 0):
                 stripe_count = lov.stripe_cnt
             else:
-                stripe_count = len(lov.devlist)
+                stripe_count = 1
             if stripe_count > 77:
                 self.inode_size = 4096
             elif stripe_count > 34:
                 self.inode_size = 2048
             elif stripe_count > 13:
                 self.inode_size = 1024
-            elif stripe_count > 2:
-                self.inode_size = 512
+            #elif stripe_count < 3:
+            #    self.inode_size = 256
             else:
-                self.inode_size = 256
+                self.inode_size = 512
+
+        debug('stripe_count %d, inode_size %d', stripe_count, self.inode_size)
 
         self.target_dev_uuid = self.uuid
         self.uuid = target_uuid
@@ -1776,7 +1875,7 @@ class MDSDEV(Module):
                         noexec_opt = ('', '-n')
                         ret, out = run (sys.argv[0],
                                         noexec_opt[old_noexec == 1],
-                                        " -v --record --nomod",
+                                        " --record --nomod",
                                         "--record_log", client_name,
                                         "--record_device", self.name,
                                         "--node", client_name,
@@ -1865,9 +1964,19 @@ class OSD(Module):
         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)
-        self.mkfsoptions = '-i 16384 ' + self.db.get_val('mkfsoptions', '')
+        self.mkfsoptions = self.db.get_val('mkfsoptions', '')
+        # Allocate fewer inodes on large OST devices.  Most filesystems
+        # can be much more aggressive than this, but by default we can't.
+        if self.size > 1000000:
+                self.mkfsoptions = '-i 16384 ' + self.mkfsoptions
         self.mountfsoptions = self.db.get_val('mountfsoptions', '')
+
         self.fstype = self.db.get_val('fstype', '')
+        if sys_get_branch() == '2.4' and self.fstype == 'ldiskfs':
+            self.fstype = 'ext3'
+        elif sys_get_branch() == '2.6' and self.fstype == 'ext3':
+            self.fstype = 'ldiskfs'
+
         self.nspath = self.db.get_val('nspath', '')
         target_uuid = self.db.get_first_ref('target')
         ost = self.db.lookup(target_uuid)
@@ -1885,7 +1994,7 @@ class OSD(Module):
             self.active = 1
         else:
             self.active = 0
-        if self.active and config.group and config.group != ost.get_val('group'):
+        if self.active and config.group and config.group != ost.get_val('group', ost.get_val('name')):
             self.active = 0
 
         self.target_dev_uuid = self.uuid
@@ -1999,7 +2108,7 @@ class Client(Module):
         self.target_name = tgtdb.getName()
         self.target_uuid = tgtdb.getUUID()
         self.db = tgtdb
-       self.backup_targets = []
+        self.backup_targets = []
 
         self.tgt_dev_uuid = get_active_target(tgtdb)
         if not self.tgt_dev_uuid:
@@ -2982,6 +3091,7 @@ lconf_options = [
     ('subsystem', "Set the portals debug subsystem",  PARAM),
     ('gdb_script', "Fullname of gdb debug script", PARAM, default_gdb_script()),
     ('debug_path', "Path to save debug dumps", PARAM, default_debug_path()),
+    ('allow_unprivileged_port', "Allow connections from unprivileged ports"),
 # Client recovery options
     ('recover', "Recover a device"),
     ('group', "The group of devices to configure or cleanup", PARAM),