Whamcloud - gitweb
b=965
authorrread <rread>
Fri, 28 Mar 2003 07:55:40 +0000 (07:55 +0000)
committerrread <rread>
Fri, 28 Mar 2003 07:55:40 +0000 (07:55 +0000)
- lconf gets a new option, --recover and will do recovery for a connection on the client

- fix bug reported by Morrone where a client would use the elan nid even
  when it wanted to use tcp. (untested)

- And the bulk of this patch is a consolidation of the command line processing
  for the python tools.  Now all options are displayed in the usage string,
  and includes the defaults if any.  It's also trivial to add new options now.

lustre/utils/Lustre/__init__.py
lustre/utils/Lustre/cmdline.py [new file with mode: 0644]
lustre/utils/Lustre/error.py
lustre/utils/Lustre/lustredb.py
lustre/utils/lactive

index 09e98b9..a4f4367 100644 (file)
@@ -1,4 +1,5 @@
 __all__ = ["lustredb"]
 
 from lustredb import LustreDB, LustreDB_XML, LustreDB_LDAP
-from error import LconfError
+from error import LconfError, OptionError
+from cmdline import Options
diff --git a/lustre/utils/Lustre/cmdline.py b/lustre/utils/Lustre/cmdline.py
new file mode 100644 (file)
index 0000000..fa1e611
--- /dev/null
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+#
+#  Copyright (C) 2002 Cluster File Systems, Inc.
+#   Author: Robert Read <rread@clusterfs.com>
+#   This file is part of Lustre, http://www.lustre.org.
+#
+#   Lustre is free software; you can redistribute it and/or
+#   modify it under the terms of version 2 of the GNU General Public
+#   License as published by the Free Software Foundation.
+#
+#   Lustre is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with Lustre; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# Standard the comand line handling for all the python tools.
+
+import sys, getopt, types
+import string
+import error
+
+class Options:
+    FLAG = 1
+    PARAM = 2
+    def __init__(self, cmd, remain_help, options):
+        self.options = options
+        shorts = ""
+        longs = []
+        options.append(('help,h', "Print this help")) 
+        for opt in options:
+            long = self.long(opt)
+            short = self.short(opt)
+            if self.type(opt) == Options.PARAM:
+                if short:  short = short + ':'
+                if long: long = long + '='
+            shorts = shorts + short
+            longs.append(long)
+        self.short_opts = shorts
+        self.long_opts = longs
+        self.cmd = cmd
+        self.remain_help = remain_help
+
+    def init_values(self):
+        values = {}
+        for opt in self.options:
+            values[self.long(opt)] = self.default(opt)
+        return values
+
+    def long(self, option):
+        n = string.find(option[0], ',')
+        if n < 0: return option[0]
+        else:     return option[0][0:n]
+
+    def short(self, option):
+        n = string.find(option[0], ',')
+        if n < 0: return ''
+        else:     return option[0][n+1:]
+
+    def help(self, option):
+        return option[1]
+    
+    def type(self, option):
+        if len(option) >= 3:
+            return option[2]
+        return Options.FLAG
+    
+    def default(self, option):
+        if len(option) >= 4:
+            return option[3]
+        return None
+
+    def lookup_option(self, key, key_func):
+        for opt in self.options:
+            if key_func(opt) == key:
+                return opt
+
+    def lookup_short(self, key):
+        return self.lookup_option(key, self.short)
+
+    def lookup_long(self, key):
+        return self.lookup_option(key, self.long)
+
+    def handle_opts(self, opts):
+        values = self.init_values()
+        for o, a in opts:
+            if o[0:2] != '--':
+                option = self.lookup_short(o[1:])
+            else:
+                option = self.lookup_long(o[2:])
+            if self.type(option) == Options.PARAM:
+                val = a
+            else:
+                val = 1
+            values[self.long(option)] = val
+        return values
+                
+    class option_wrapper:
+        def __init__(self, values):
+            self.__dict__['values'] = values
+        def __getattr__(self, name):
+            if self.values.has_key(name):
+                return self.values[name]
+            else:
+                raise error.OptionError("bad option name: " + name)
+        def __setattr__(self, name, value):
+            self.values[name] = value
+
+    def parse(self, argv):
+        try:
+            opts, args = getopt.getopt(argv, self.short_opts, self.long_opts)
+            values = self.handle_opts(opts)
+            if values["help"]:
+                self.usage()
+                sys.exit(0)
+            return self.option_wrapper(values), args
+        except getopt.error, e:
+            raise error.OptionError(e)
+
+    def usage(self):
+        ret = 'usage: %s [options] %s\n' % (self.cmd, self.remain_help)
+        for opt in self.options:
+            s = self.short(opt)
+            if s: str = "-%s|--%s" % (s,self.long(opt))
+            else: str = "--%s" % (self.long(opt),)
+            if self.type(opt) == Options.PARAM:
+                str = "%s <arg>" % (str,)
+            help = self.help(opt)
+            n = string.find(help, '\n')
+            if self.default(opt) != None:
+                if n < 0:
+                    str = "%-15s  %s (default=%s)" %(str, help,
+                                                     self.default(opt))
+                else:
+                    str = "%-15s  %s (default=%s)%s" %(str, help[0:n],
+                                                       self.default(opt),
+                                                       help[n:])
+            else:
+                str = "%-15s  %s" %(str, help)
+            ret = ret + str + "\n"
+        print ret
+
+# Test driver
+if __name__ == "__main__":
+    cl = Options("test", "xml_file", [
+                  ('verbose,v', "verbose ", Options.FLAG, 0),
+                  ('cleanup,d', "shutdown"),
+                  ('gdb',     "Display gdb module file ", Options.FLAG, 0),
+                  ('device', "device path ", Options.PARAM),
+                  ('ldapurl', "LDAP server URL ", Options.PARAM),
+                  ('lustre', "Lustre source dir ", Options.PARAM),
+                  ('portals', "Portals source dir ", Options.PARAM),
+                  ('maxlevel', """Specify the maximum level
+                    Levels are aproximatly like:
+                            70 - mountpoint, echo_client, osc, mdc, lov""",
+                   Options.PARAM, 100),
+
+                  ])
+
+    conf, args = cl.parse(sys.argv[1:])
+
+    for key in conf.values.keys():
+        print "%-10s = %s" % (key, conf.values[key])
index ddaaac9..6c30416 100644 (file)
@@ -4,3 +4,7 @@ class LconfError (exceptions.Exception):
     def __init__(self, args):
         self.args = args
 
+class OptionError (exceptions.Exception):
+    def __init__(self, args):
+        self.args = args
+
index 4e0b504..14be906 100644 (file)
@@ -66,19 +66,11 @@ class LustreDB:
     
     # Find the target_device for target on a node
     # node->profiles->device_refs->target
-    def get_target_device(self, target_uuid, node_name):
+    def get_node_tgt_dev(self, node_name, target_uuid):
         node_db = self.lookup_name(node_name)
         if not node_db:
             return None
-        prof_list = node_db.get_refs('profile')
-        for prof_uuid in prof_list:
-            prof_db = node_db.lookup(prof_uuid)
-            ref_list = prof_db.get_all_refs()
-            for ref in ref_list:
-                dev = self.lookup(ref[1])
-                if dev and dev.get_first_ref('target') == target_uuid:
-                    return ref[1]
-        return None
+        return self.get_tgt_dev(target_uuid)
 
     # get all network uuids for this node
     def get_networks(self):
@@ -91,6 +83,25 @@ class LustreDB:
                 ret.append(net_uuid)
         return ret
 
+    def get_active_dev(self, tgtuuid):
+        tgt = self.lookup(tgtuuid)
+        tgt_dev_uuid =tgt.get_first_ref('active')
+        return tgt_dev_uuid
+
+    def get_tgt_dev(self, tgtuuid):
+        prof_list = self.get_refs('profile')
+        for prof_uuid in prof_list:
+            prof_db = self.lookup(prof_uuid)
+            if not prof_db:
+                panic("profile:", profile, "not found.")
+            for ref_class, ref_uuid in prof_db.get_all_refs(): 
+                if ref_class in ('osd', 'mdsdev'):
+                    devdb = self.lookup(ref_uuid)
+                    uuid = devdb.get_first_ref('target')
+                    if tgtuuid == uuid:
+                        return ref_uuid
+        return None
+
     # Change the current active device for a target
     def update_active(self, tgtuuid, new_uuid):
         self._update_active(tgtuuid, new_uuid)
@@ -125,6 +136,10 @@ class LustreDB_XML(LustreDB):
     def _get_class(self):
         return self.dom_node.nodeName
 
+    def get_ref_type(self, ref_tag):
+        res = string.split(ref_tag, '_')
+        return res[0]
+
     #
     # [(ref_class, ref_uuid),]
     def _get_all_refs(self):
@@ -132,7 +147,7 @@ class LustreDB_XML(LustreDB):
         for n in self.dom_node.childNodes: 
             if n.nodeType == n.ELEMENT_NODE:
                 ref_uuid = self.xml_get_ref(n)
-                ref_class = n.nodeName
+                ref_class = self.get_ref_type(n.nodeName)
                 list.append((ref_class, ref_uuid))
                     
         list.sort()
@@ -326,6 +341,9 @@ class LustreDB_LDAP(LustreDB):
     def _get_class(self):
         return string.lower(self._attrs['objectClass'][0])
 
+    def get_ref_type(self, ref_tag):
+        return ref_tag[:-3]
+
     #
     # [(ref_class, ref_uuid),]
     def _get_all_refs(self):
@@ -333,7 +351,8 @@ class LustreDB_LDAP(LustreDB):
         for k in self._attrs.keys():
             if re.search('.*Ref', k):
                 for uuid in self._attrs[k]:
-                    list.append((k, uuid))
+                    ref_class = self.get_ref_type(k)
+                    list.append((ref_class, uuid))
         return list
 
     def _get_refs(self, tag):
@@ -360,7 +379,6 @@ class LustreDB_LDAP(LustreDB):
         ret = []
         uuids = []
         try:
-            print tgtuuid, newuuid
             self.l.modify_s(dn, [(ldap.MOD_REPLACE, "activeRef", newuuid)])
         except ldap.NO_SUCH_OBJECT, e:
             print e
index a3a3093..6fd5815 100644 (file)
@@ -30,85 +30,43 @@ import string, os
 import ldap
 import Lustre
 
+lactive_options = [
+    ('ldapurl',"LDAP server URL, eg. ldap://localhost", Lustre.Options.PARAM),
+    ('config', "Cluster config name used for LDAP query", Lustre.Options.PARAM),
+    ('old', "The old, failed node name", Lustre.Options.PARAM),
+    ('new', "The new node name", Lustre.Options.PARAM),
+    ]
 
-def usage():
-    print """usage: lactive --ldapurl <ldapurl> --old <name> --new <name>"""
-    sys.exit(1)
-    
-def parse_cmdline(argv):
-    short_opts = "h"
-    long_opts = ["help", "new=", "old=", "ldapurl=",]
-    opts = []
-    args = []
-    config = {}
+cl = Lustre.Options("lactive","", lactive_options)
+config, args = cl.parse(sys.argv[1:])
 
-    try:
-        opts, args = getopt.getopt(argv, short_opts, long_opts)
-    except getopt.error:
-        print "invalid opt"
-        usage()
-    
-    for o, a in opts:
-        if o in ("-h", "--help"):
-            usage()
-        if o in ("--old",):
-            config['old'] = a
-        if o in ("--new",):
-            config['new'] = a
-        if o in ("--ldapurl",):
-            config['ldapurl'] = a
+base = "config=%s,fs=lustre" % (config.config,)
+db = Lustre.LustreDB_LDAP('', {}, base=base, url = config.ldapurl)
 
-    return config
-
-def get_active(db, tgtuuid):
-    tgt = db.lookup(tgtuuid)
-    tgt_dev_uuid =tgt.get_first_ref('active')
-    return tgt_dev_uuid
-
-def get_inactive(db, tgtuuid):
-    prof_list = db.get_refs('profile')
-    for prof_uuid in prof_list:
-        prof_db = db.lookup(prof_uuid)
-        if not prof_db:
-            panic("profile:", profile, "not found.")
-        for ref_class, ref_uuid in prof_db.get_all_refs(): 
-            if ref_class in ('osdRef', 'mdsdevRef'):
-                devdb = db.lookup(ref_uuid)
-                uuid = devdb.get_first_ref('target')
-                if tgtuuid == uuid:
-                    return ref_uuid
-    return None
-
-
-config = parse_cmdline(sys.argv[1:])
-
-db = Lustre.LustreDB_LDAP('', {}, base="config=test23,fs=lustre",
-                          url = config['ldapurl'])
-
-old = db.lookup_name(config['old'])
-new = db.lookup_name(config['new'])
+old = db.lookup_name(config.old)
+new = db.lookup_name(config.new)
 
 print "old:", old.getUUID()
 print "new:",  new.getUUID()
 
 # find all the targets on the failed node and, change the active
-# pointers to point to the devices on the new node.  
+# pointers to point to the devices on the new node.
 prof_list = old.get_refs('profile')
 for prof_uuid in prof_list:
     prof_db = db.lookup(prof_uuid)
     if not prof_db:
         panic("profile:", profile, "not found.")
     for ref_class, ref_uuid in prof_db.get_all_refs(): 
-        if ref_class in ('osdRef', 'mdsdevRef'):
+        if ref_class in ('osd', 'mdsdev'):
             devdb = db.lookup(ref_uuid)
             tgtuuid = devdb.get_first_ref('target')
-            active_uuid = get_active(old, tgtuuid)
+            active_uuid = old.get_active_dev(tgtuuid)
             if ref_uuid != active_uuid:
                 continue
-            inactive_uuid = get_inactive(new, tgtuuid)
+            inactive_uuid = new.get_tgt_dev(tgtuuid)
             print ("%s: changing active %s:%s to %s:%s"
-                   % (tgtuuid, config['old'], active_uuid,
-                      config['new'], inactive_uuid))
+                   % (tgtuuid, config.old, active_uuid,
+                      config.new, inactive_uuid))
             db.update_active(tgtuuid, inactive_uuid)