3 # Copyright (C) 2002 Cluster File Systems, Inc.
4 # Author: Robert Read <rread@clusterfs.com>
6 # This file is part of Lustre, http://www.lustre.org.
8 # Lustre is free software; you can redistribute it and/or
9 # modify it under the terms of version 2 of the GNU General Public
10 # License as published by the Free Software Foundation.
12 # Lustre is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Lustre; if not, write to the Free Software
19 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 # lconf - lustre configuration tool
23 # lconf is the main driver script for starting and stopping
24 # lustre filesystem services.
26 # Based in part on the XML obdctl modifications done by Brian Behlendorf
29 import string, os, stat, popen2, socket, time
31 import xml.dom.minidom
37 # Maximum number of devices to search for.
38 # (the /dev/loop* nodes need to be created beforehand)
39 MAX_LOOP_DEVICES = 256
43 print """usage: lconf config.xml
45 config.xml Lustre configuration in xml format.
46 --get <url> URL to fetch a config file
47 --node <nodename> Load config for <nodename>
48 -d | --cleanup Cleans up config. (Shutdown)
49 -v | --verbose Print system commands as they are run
50 -h | --help Print this help
51 --gdb Prints message after creating gdb module script
52 and sleeps for 5 seconds.
53 -n | --noexec Prints the commands and steps that will be run for a
54 config without executing them. This can used to check if a
55 config file is doing what it should be doing. (Implies -v)
56 --nomod Skip load/unload module step.
57 --nosetup Skip device setup/cleanup step.
60 --ldap server LDAP server with lustre config database
61 --makeldiff Translate xml source to LDIFF
62 --reformat Reformat all devices (will confirm)
63 This are perhaps not needed:
64 --lustre="src dir" Base directory of lustre sources. Used to search
66 --portals=src Portals source
70 # ============================================================
71 # Config parameters, encapsulated in a class
86 self._gdb_script = '/tmp/ogdb'
87 self._debug_path = '/tmp/lustre-log'
90 def verbose(self, flag = None):
91 if flag: self._verbose = flag
94 def noexec(self, flag = None):
95 if flag: self._noexec = flag
98 def reformat(self, flag = None):
99 if flag: self._reformat = flag
100 return self._reformat
102 def cleanup(self, flag = None):
103 if flag: self._cleanup = flag
106 def gdb(self, flag = None):
107 if flag: self._gdb = flag
110 def nomod(self, flag = None):
111 if flag: self._nomod = flag
114 def nosetup(self, flag = None):
115 if flag: self._nosetup = flag
118 def node(self, val = None):
119 if val: self._node = val
122 def url(self, val = None):
123 if val: self._url = val
126 def gdb_script(self):
127 if os.path.isdir('/r'):
128 return '/r' + self._gdb_script
130 return self._gdb_script
132 def debug_path(self):
133 if os.path.isdir('/r'):
134 return '/r' + self._debug_path
136 return self._debug_path
138 def src_dir(self, val = None):
139 if val: self._url = val
144 # ============================================================
145 # debugging and error funcs
147 def fixme(msg = "this feature"):
148 raise LconfError, msg + ' not implmemented yet.'
151 msg = string.join(map(str,args))
152 if not config.noexec():
153 raise LconfError(msg)
156 msg = string.join(map(str,args))
161 print string.strip(s)
165 msg = string.join(map(str,args))
168 # ============================================================
169 # locally defined exceptions
170 class CommandError (exceptions.Exception):
171 def __init__(self, cmd_name, cmd_err, rc=None):
172 self.cmd_name = cmd_name
173 self.cmd_err = cmd_err
178 if type(self.cmd_err) == types.StringType:
180 print "! %s (%d): %s" % (self.cmd_name, self.rc, self.cmd_err)
182 print "! %s: %s" % (self.cmd_name, self.cmd_err)
183 elif type(self.cmd_err) == types.ListType:
185 print "! %s (error %d):" % (self.cmd_name, self.rc)
187 print "! %s:" % (self.cmd_name)
188 for s in self.cmd_err:
189 print "> %s" %(string.strip(s))
193 class LconfError (exceptions.Exception):
194 def __init__(self, args):
198 # ============================================================
199 # handle lctl interface
202 Manage communication with lctl
205 def __init__(self, cmd):
207 Initialize close by finding the lctl binary.
209 self.lctl = find_prog(cmd)
212 debug('! lctl not found')
215 raise CommandError('lctl', "unable to find lctl binary.")
220 the cmds are written to stdin of lctl
221 lctl doesn't return errors when run in script mode, so
223 should modify command line to accept multiple commands, or
224 create complex command line options
226 debug("+", self.lctl, cmds)
227 if config.noexec(): return (0, [])
228 p = popen2.Popen3(self.lctl, 1)
229 p.tochild.write(cmds + "\n")
231 out = p.fromchild.readlines()
232 err = p.childerr.readlines()
235 raise CommandError(self.lctl, err, ret)
239 def network(self, net, nid):
240 """ initialized network and add "self" """
241 # Idea: "mynid" could be used for all network types to add "self," and then
242 # this special case would be gone and the "self" hack would be hidden.
248 quit""" % (net, nid, nid)
257 # create a new connection
258 def connect(self, net, nid, port, servuuid, send_buf, read_buf):
259 # XXX: buf size params not used yet
264 quit""" % (net, nid, port, servuuid, nid)
267 # create a new connection
268 def add_route(self, net, to, via):
273 # disconnect one connection
274 def disconnect(self, net, nid, port, servuuid):
279 quit""" % (net, nid, servuuid)
282 # disconnect all connections
283 def disconnectAll(self, net):
291 # create a new device with lctl
292 def newdev(self, attach, setup = ""):
297 quit""" % (attach, setup)
301 def cleanup(self, name, uuid):
310 def lovconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist):
314 lovconfig %s %d %d %d %s %s
315 quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist)
318 # ============================================================
319 # Various system-level functions
320 # (ideally moved to their own module)
322 # Run a command and return the output and status.
323 # stderr is sent to /dev/null, could use popen3 to
324 # save it if necessary
326 cmd = string.join(map(str,args))
328 if config.noexec(): return (0, [])
329 f = os.popen(cmd + ' 2>&1')
338 # Run a command in the background.
339 def run_daemon(*args):
340 cmd = string.join(map(str,args))
342 if config.noexec(): return 0
343 f = os.popen(cmd + ' 2>&1')
351 # Determine full path to use for an external command
352 # searches dirname(argv[0]) first, then PATH
354 syspath = string.split(os.environ['PATH'], ':')
355 cmdpath = os.path.dirname(sys.argv[0])
356 syspath.insert(0, cmdpath);
357 syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/'))
359 prog = os.path.join(d,cmd)
360 if os.access(prog, os.X_OK):
364 # Recursively look for file starting at base dir
365 def do_find_file(base, mod):
366 fullname = os.path.join(base, mod)
367 if os.access(fullname, os.R_OK):
369 for d in os.listdir(base):
370 dir = os.path.join(base,d)
371 if os.path.isdir(dir):
372 module = do_find_file(dir, mod)
376 def find_module(src_dir, modname):
377 mod = '%s.o' % (modname)
378 search = (src_dir + "/lustre", src_dir + "/portals/linux")
381 module = do_find_file(d, mod)
388 # is the path a block device?
395 return stat.S_ISBLK(s[stat.ST_MODE])
397 # build fs according to type
399 def mkfs(fstype, dev):
400 if(fstype in ('ext3', 'extN')):
401 mkfs = 'mkfs.ext2 -j -b 4096'
403 print 'unsupported fs type: ', fstype
404 if not is_block(dev):
408 (ret, out) = run (mkfs, force, dev)
410 panic("Unable to build fs:", dev)
411 # enable hash tree indexing on fs
413 htree = 'echo "feature FEATURE_C5" | debugfs -w'
414 (ret, out) = run (htree, dev)
416 panic("Unable to enable htree:", dev)
418 # some systems use /dev/loopN, some /dev/loop/N
422 if not os.access(loop + str(0), os.R_OK):
424 if not os.access(loop + str(0), os.R_OK):
425 panic ("can't access loop devices")
428 # find loop device assigned to thefile
431 for n in xrange(0, MAX_LOOP_DEVICES):
433 if os.access(dev, os.R_OK):
434 (stat, out) = run('losetup', dev)
435 if (out and stat == 0):
436 m = re.search(r'\((.*)\)', out[0])
437 if m and file == m.group(1):
443 # create file if necessary and assign the first free loop device
444 def init_loop(file, size, fstype):
445 dev = find_loop(file)
447 print 'WARNING file:', file, 'already mapped to', dev
449 if not os.access(file, os.R_OK | os.W_OK):
450 run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, file))
452 # find next free loop
453 for n in xrange(0, MAX_LOOP_DEVICES):
455 if os.access(dev, os.R_OK):
456 (stat, out) = run('losetup', dev)
458 run('losetup', dev, file)
461 print "out of loop devices"
463 print "out of loop devices"
466 # undo loop assignment
467 def clean_loop(file):
468 dev = find_loop(file)
470 ret, out = run('losetup -d', dev)
472 log('unable to clean loop device:', dev, 'for file:', file)
475 # determine if dev is formatted as a <fstype> filesystem
476 def need_format(fstype, dev):
477 # FIXME don't know how to implement this
480 # initialize a block device if needed
481 def block_dev(dev, size, fstype, format):
482 if config.noexec(): return dev
483 if not is_block(dev):
484 dev = init_loop(dev, size, fstype)
485 if config.reformat() or (need_format(fstype, dev) and format == 'yes'):
489 # panic("device:", dev,
490 # "not prepared, and autoformat is not set.\n",
491 # "Rerun with --reformat option to format ALL filesystems")
495 def get_local_address(net_type):
496 """Return the local address for the network type."""
498 if net_type == 'tcp':
500 host = socket.gethostname()
501 local = socket.gethostbyname(host)
502 elif net_type == 'elan':
503 # awk '/NodeId/ { print $2 }' '/proc/elan/device0/position'
505 fp = open('/proc/elan/device0/position', 'r')
506 lines = fp.readlines()
515 elif net_type == 'gm':
516 fixme("automatic local address for GM")
521 # ============================================================
522 # Classes to prepare and cleanup the various objects
525 """ Base class for the rest of the modules. The default cleanup method is
526 defined here, as well as some utilitiy funcs.
528 def __init__(self, tag_name, node):
530 self.tag_name = tag_name
531 self.name = node.getAttribute('name')
532 self.uuid = node.getAttribute('uuid')
533 self.kmodule_list = []
535 def info(self, *args):
536 msg = string.join(map(str,args))
537 print self.tag_name + ":", self.name, self.uuid, msg
540 """ default cleanup, used for most modules """
543 lctl.cleanup(self.name, self.uuid)
544 except CommandError, e:
545 print "cleanup failed: ", self.name
547 def add_module(self, modname):
548 """Append a module to list of modules to load."""
549 self.kmodule_list.append(modname)
551 def mod_loaded(self, modname):
552 """Check if a module is already loaded. Look in /proc/modules for it."""
553 fp = open('/proc/modules')
554 lines = fp.readlines()
556 # please forgive my tired fingers for this one
557 ret = filter(lambda word, mod=modname: word == mod,
558 map(lambda line: string.split(line)[0], lines))
561 def load_module(self):
562 """Load all the modules in the list in the order they appear."""
563 for mod in self.kmodule_list:
564 # (rc, out) = run ('/sbin/lsmod | grep -s', mod)
565 if self.mod_loaded(mod) and not config.noexec():
567 log ('loading module:', mod)
569 module = find_module(config.src_dir(), mod)
571 panic('module not found:', mod)
572 (rc, out) = run('/sbin/insmod', module)
574 raise CommandError('insmod', out, rc)
576 (rc, out) = run('/sbin/modprobe', mod)
578 raise CommandError('modprobe', out, rc)
580 def cleanup_module(self):
581 """Unload the modules in the list in reverse order."""
582 rev = self.kmodule_list
585 if not self.mod_loaded(mod):
587 log('unloading module:', mod)
590 (rc, out) = run('/sbin/rmmod', mod)
592 log('! unable to unload module:', mod)
596 class Network(Module):
597 def __init__(self,node):
598 Module.__init__(self, 'NETWORK', node)
599 self.net_type = node.getAttribute('type')
600 self.nid = getText(node, 'server', '*')
601 self.port = int(getText(node, 'port', 0))
602 self.send_buf = int(getText(node, 'send_buf', 0))
603 self.read_buf = int(getText(node, 'read_buf', 0))
605 self.nid = get_local_address(self.net_type)
607 panic("unable to set nid for", self.net_type)
609 self.add_module('portals')
610 if self.net_type == 'tcp':
611 self.add_module('ksocknal')
612 if self.net_type == 'elan':
613 self.add_module('kqswnal')
614 if self.net_type == 'gm':
615 self.add_module('kgmnal')
616 self.add_module('obdclass')
617 self.add_module('ptlrpc')
620 self.info(self.net_type, self.nid, self.port)
621 if self.net_type == 'tcp':
622 ret = run_daemon(TCP_ACCEPTOR, self.port)
624 raise CommandError(TCP_ACCEPTOR, 'failed', ret)
625 lctl.network(self.net_type, self.nid)
626 lctl.newdev(attach = "ptlrpc RPCDEV")
629 self.info(self.net_type, self.nid, self.port)
631 lctl.cleanup("RPCDEV", "")
632 except CommandError, e:
633 print "cleanup failed: ", self.name
635 lctl.disconnectAll(self.net_type)
636 except CommandError, e:
637 print "cleanup failed: ", self.name
638 if self.net_type == 'tcp':
639 # yikes, this ugly! need to save pid in /var/something
640 run("killall acceptor")
643 def __init__(self,node):
644 Module.__init__(self, 'LDLM', node)
645 self.add_module('ldlm')
648 lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid),
652 def __init__(self,node):
653 Module.__init__(self, 'LOV', node)
654 devs = node.getElementsByTagName('devices')[0]
655 self.stripe_sz = int(devs.getAttribute('stripesize'))
656 self.stripe_off = int(devs.getAttribute('stripeoffset'))
657 self.pattern = int(devs.getAttribute('pattern'))
658 mdsref = node.getElementsByTagName('mds_ref')[0]
659 self.mdsuuid = mdsref.getAttribute('uuidref')
660 mds= lookup(node.parentNode, self.mdsuuid)
661 self.mdsname = getName(mds)
664 for child in devs.childNodes:
665 if child.nodeName == 'osc_ref':
666 devlist = devlist + child.getAttribute('uuidref') + " "
667 stripe_cnt = stripe_cnt + 1
668 self.devlist = devlist
669 self.stripe_cnt = stripe_cnt
670 self.add_module('osc')
671 self.add_module('lov')
674 self.info(self.mdsuuid, self.stripe_cnt, self.stripe_sz, self.stripe_off, self.pattern,
675 self.devlist, self.mdsname)
676 lctl.lovconfig(self.uuid, self.mdsname, self.stripe_cnt,
677 self.stripe_sz, self.stripe_off, self.pattern,
684 def __init__(self,node):
685 Module.__init__(self, 'MDS', node)
686 self.devname, self.size = getDevice(node)
687 self.fstype = getText(node, 'fstype')
688 self.format = getText(node, 'autoformat', "no")
689 if self.fstype == 'extN':
690 self.add_module('extN')
691 self.add_module('mds')
692 self.add_module('mds_%s' % (self.fstype))
695 self.info(self.devname, self.fstype, self.format)
696 blkdev = block_dev(self.devname, self.size, self.fstype, self.format)
697 lctl.newdev(attach="mds %s %s" % (self.name, self.uuid),
698 setup ="%s %s" %(blkdev, self.fstype))
701 clean_loop(self.devname)
704 def __init__(self,node):
705 Module.__init__(self, 'MDC', node)
706 ref = node.getElementsByTagName('mds_ref')[0]
707 self.mds_uuid = ref.getAttribute('uuidref')
708 self.add_module('mdc')
711 self.info(self.mds_uuid)
712 mds = lookup(self.dom_node.parentNode, self.mds_uuid)
714 panic(self.mdsuuid, "not found.")
715 net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
717 lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
718 lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid),
719 setup ="%s %s" %(self.mds_uuid, srv.uuid))
722 self.info(self.mds_uuid)
723 net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
726 lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
728 print "disconnect failed: ", self.name
730 lctl.cleanup(self.name, self.uuid)
732 print "cleanup failed: ", self.name
735 def __init__(self, node):
736 Module.__init__(self, 'OBD', node)
737 self.obdtype = node.getAttribute('type')
738 self.devname, self.size = getDevice(node)
739 self.fstype = getText(node, 'fstype')
740 self.format = getText(node, 'autoformat', 'yes')
741 if self.fstype == 'extN':
742 self.add_module('extN')
743 self.add_module(self.obdtype)
745 # need to check /proc/mounts and /etc/mtab before
746 # formatting anything.
747 # FIXME: check if device is already formatted.
749 self.info(self.obdtype, self.devname, self.size, self.fstype, self.format)
750 if self.obdtype == 'obdecho':
753 blkdev = block_dev(self.devname, self.size, self.fstype, self.format)
754 lctl.newdev(attach="%s %s %s" % (self.obdtype, self.name, self.uuid),
755 setup ="%s %s" %(blkdev, self.fstype))
758 if not self.obdtype == 'obdecho':
759 clean_loop(self.devname)
762 def __init__(self,node):
763 Module.__init__(self, 'OST', node)
764 ref = node.getElementsByTagName('obd_ref')[0]
765 self.obd_uuid = ref.getAttribute('uuidref')
766 self.add_module('ost')
769 self.info(self.obd_uuid)
770 lctl.newdev(attach="ost %s %s" % (self.name, self.uuid),
771 setup ="%s" % (self.obd_uuid))
774 def __init__(self,node):
775 Module.__init__(self, 'OSC', node)
776 ref = node.getElementsByTagName('obd_ref')[0]
777 self.obd_uuid = ref.getAttribute('uuidref')
778 ref = node.getElementsByTagName('ost_ref')[0]
779 self.ost_uuid = ref.getAttribute('uuidref')
780 self.add_module('osc')
783 self.info(self.obd_uuid, self.ost_uuid)
784 net = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
786 lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
787 lctl.newdev(attach="osc %s %s" % (self.name, self.uuid),
788 setup ="%s %s" %(self.obd_uuid, srv.uuid))
791 self.info(self.obd_uuid, self.ost_uuid)
792 net_uuid = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
793 srv = Network(net_uuid)
795 lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
797 print " failed: ", self.name
799 lctl.cleanup(self.name, self.uuid)
801 print "cleanup failed: ", self.name
803 class Mountpoint(Module):
804 def __init__(self,node):
805 Module.__init__(self, 'MTPT', node)
806 self.path = getText(node, 'path')
807 ref = node.getElementsByTagName('mdc_ref')[0]
808 self.mdc_uuid = ref.getAttribute('uuidref')
809 ref = node.getElementsByTagName('osc_ref')[0]
810 self.lov_uuid = ref.getAttribute('uuidref')
811 self.add_module('osc')
812 self.add_module('llite')
815 l = lookup(self.dom_node.parentNode, self.lov_uuid)
816 if l.nodeName == 'lov':
818 for osc_uuid in string.split(lov.devlist):
819 osc = lookup(self.dom_node.parentNode, osc_uuid)
824 panic('osc not found:', osc_uuid)
825 lctl.newdev(attach="lov %s %s" % (lov.name, lov.uuid),
826 setup ="%s" % (self.mdc_uuid))
831 self.info(self.path, self.mdc_uuid,self.lov_uuid)
832 cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \
833 (self.lov_uuid, self.mdc_uuid, self.path)
834 run("mkdir", self.path)
837 panic("mount failed:", self.path)
839 self.info(self.path, self.mdc_uuid,self.lov_uuid)
840 run("umount", self.path)
841 l = lookup(self.dom_node.parentNode, self.lov_uuid)
842 if l.nodeName == 'lov':
844 for osc_uuid in string.split(lov.devlist):
845 osc = lookup(self.dom_node.parentNode, osc_uuid)
850 panic('osc not found:', osc_uuid)
856 # ============================================================
857 # XML processing and query
858 # TODO: Change query funcs to use XPath, which is muc cleaner
861 list = obd.getElementsByTagName('device')
866 size = int(dev.getAttribute('size'))
869 return dev.firstChild.data, size
872 # Get the text content from the first matching child
873 # If there is no content (or it is all whitespace), return
875 def getText(node, tag, default=""):
876 list = node.getElementsByTagName(tag)
881 txt = string.strip(node.firstChild.data)
886 def get_ost_net(node, uuid):
887 ost = lookup(node, uuid)
888 list = ost.getElementsByTagName('network_ref')
890 uuid = list[0].getAttribute('uuidref')
893 return lookup(node, uuid)
895 def lookup(node, uuid):
896 for n in node.childNodes:
897 if n.nodeType == n.ELEMENT_NODE:
898 if getUUID(n) == uuid:
905 # Get name attribute of node
907 return node.getAttribute('name')
910 return node.getAttribute('uuidref')
912 # Get name attribute of node
914 return node.getAttribute('uuid')
916 # the tag name is the service type
917 # fixme: this should do some checks to make sure the node is a service
918 def getServiceType(node):
922 # determine what "level" a particular node is at.
923 # the order of iniitailization is based on level. objects
924 # are assigned a level based on type:
925 # net,devices,ldlm:1, obd, mdd:2 mds,ost:3 osc,mdc:4 mounts:5
926 def getServiceLevel(node):
927 type = getServiceType(node)
928 if type in ('network',):
930 if type in ('device', 'ldlm'):
932 elif type in ('obd', 'mdd'):
934 elif type in ('mds','ost'):
936 elif type in ('mdc','osc'):
938 elif type in ('lov',):
940 elif type in ('mountpoint',):
945 # return list of services in a profile. list is a list of tuples
947 def getServices(lustreNode, profileNode):
949 for n in profileNode.childNodes:
950 if n.nodeType == n.ELEMENT_NODE:
951 servNode = lookup(lustreNode, getRef(n))
954 panic('service not found: ' + getRef(n))
955 level = getServiceLevel(servNode)
956 list.append((level, servNode))
960 def getByName(lustreNode, tag, name):
961 ndList = lustreNode.getElementsByTagName(tag)
963 if getName(nd) == name:
968 # ============================================================
971 def startService(node, clean_flag, module_flag):
972 type = getServiceType(node)
973 debug('Service:', type, getName(node), getUUID(node))
974 # there must be a more dynamic way of doing this...
980 elif type == 'network':
992 elif type == 'mountpoint':
995 panic ("unknown service type:", type)
1005 if config.nosetup():
1013 # Prepare the system to run lustre using a particular profile
1014 # in a the configuration.
1015 # * load & the modules
1016 # * setup networking for the current node
1017 # * make sure partitions are in place and prepared
1018 # * initialize devices with lctl
1019 # Levels is important, and needs to be enforced.
1020 def startProfile(lustreNode, profileNode, clean_flag, module_flag):
1022 panic("profile:", profile, "not found.")
1023 services = getServices(lustreNode, profileNode)
1027 startService(s[1], clean_flag, module_flag)
1031 def doHost(lustreNode, hosts, clean_flag):
1034 node = getByName(lustreNode, 'node', h)
1039 print 'No host entry found.'
1042 # Two step process: (1) load modules, (2) setup lustre
1043 # if not cleaning, load modules first.
1044 module_flag = not clean_flag
1045 reflist = node.getElementsByTagName('profile')
1046 for profile in reflist:
1047 startProfile(lustreNode, profile, clean_flag, module_flag)
1051 script = config.gdb_script()
1052 run(lctl.lctl, ' modules >', script)
1054 # dump /tmp/ogdb and sleep/pause here
1055 log ("The GDB module script is in", script)
1058 module_flag = not module_flag
1059 for profile in reflist:
1060 startProfile(lustreNode, profile, clean_flag, module_flag)
1062 # Command line processing
1064 def parse_cmdline(argv):
1066 long_opts = ["ldap", "reformat", "lustre=", "verbose", "gdb",
1067 "portals=", "makeldiff", "cleanup", "noexec",
1068 "help", "node=", "get=", "nomod", "nosetup"]
1072 opts, args = getopt.getopt(argv, short_opts, long_opts)
1073 except getopt.error:
1078 if o in ("-h", "--help"):
1080 if o in ("-d","--cleanup"):
1082 if o in ("-v", "--verbose"):
1084 if o in ("-n", "--noexec"):
1087 if o == "--portals":
1091 if o == "--reformat":
1101 if o == "--nosetup":
1109 s = urllib.urlopen(url)
1115 def setupModulePath(cmd):
1116 base = os.path.dirname(cmd)
1117 if os.access(base+"/Makefile", os.R_OK):
1118 config.src_dir(base + "/../../")
1121 debug("debug path: ", config.debug_path())
1125 fp = open('/proc/sys/portals/debug_path', 'w')
1126 fp.write(config.debug_path())
1133 if not os.access('/dev/portals', os.R_OK):
1134 run('mknod /dev/portals c 10 240')
1135 if not os.access('/dev/obd', os.R_OK):
1136 run('mknod /dev/obd c 10 241')
1138 # Initialize or shutdown lustre according to a configuration file
1139 # * prepare the system for lustre
1140 # * configure devices with lctl
1141 # Shutdown does steps in reverse
1144 global TCP_ACCEPTOR, lctl
1145 args = parse_cmdline(sys.argv[1:])
1147 if not os.access(args[0], os.R_OK | os.W_OK):
1148 print 'File not found:', args[0]
1150 dom = xml.dom.minidom.parse(args[0])
1152 xmldata = fetch(config.url())
1153 dom = xml.dom.minidom.parseString(xmldata)
1159 node_list.append(config.node())
1161 host = socket.gethostname()
1163 node_list.append(host)
1164 node_list.append('localhost')
1165 debug("configuring for host: ", node_list)
1167 TCP_ACCEPTOR = find_prog('acceptor')
1168 if not TCP_ACCEPTOR:
1170 TCP_ACCEPTOR = 'acceptor'
1171 debug('! acceptor not found')
1173 panic('acceptor not found')
1175 lctl = LCTLInterface('lctl')
1177 setupModulePath(sys.argv[0])
1179 doHost(dom.documentElement, node_list, config.cleanup())
1181 if __name__ == "__main__":
1184 except LconfError, e:
1186 except CommandError, e: