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 RuntimeError, msg + ' not implmemented yet.'
151 msg = string.join(map(str,args))
153 if not config.noexec():
154 raise RuntimeError, msg
157 msg = string.join(map(str,args))
162 print string.strip(s)
166 msg = string.join(map(str,args))
169 # ============================================================
170 # locally defined exceptions
171 class CommandError (exceptions.Exception):
172 def __init__(self, cmd_name, cmd_err, rc=None):
173 self.cmd_name = cmd_name
174 self.cmd_err = cmd_err
179 if type(self.cmd_err) == types.StringType:
181 print "! %s (%d): %s" % (self.cmd_name, self.rc, self.cmd_err)
183 print "! %s: %s" % (self.cmd_name, self.cmd_err)
184 elif type(self.cmd_err) == types.ListType:
186 print "! %s (error %d):" % (self.cmd_name, self.rc)
188 print "! %s:" % (self.cmd_name)
189 for s in self.cmd_err:
190 print "> %s" %(string.strip(s))
194 # ============================================================
195 # handle lctl interface
198 Manage communication with lctl
201 def __init__(self, cmd):
203 Initialize close by finding the lctl binary.
205 self.lctl = find_prog(cmd)
208 debug('! lctl not found')
211 raise CommandError('lctl', "unable to find lctl binary.")
216 the cmds are written to stdin of lctl
217 lctl doesn't return errors when run in script mode, so
219 should modify command line to accept multiple commands, or
220 create complex command line options
222 debug("+", self.lctl, cmds)
223 if config.noexec(): return (0, [])
224 p = popen2.Popen3(self.lctl, 1)
225 p.tochild.write(cmds + "\n")
227 out = p.fromchild.readlines()
228 err = p.childerr.readlines()
231 raise CommandError(self.lctl, err, ret)
235 def network(self, net, nid):
236 """ initialized network and add "self" """
237 # Idea: "mynid" could be used for all network types to add "self," and then
238 # this special case would be gone and the "self" hack would be hidden.
244 quit""" % (net, nid, nid)
253 # create a new connection
254 def connect(self, net, nid, port, servuuid, send_buf, read_buf):
255 # XXX: buf size params not used yet
260 quit""" % (net, nid, port, servuuid, nid)
263 # create a new connection
264 def add_route(self, net, to, via):
269 # disconnect one connection
270 def disconnect(self, net, nid, port, servuuid):
275 quit""" % (net, nid, servuuid)
278 # disconnect all connections
279 def disconnectAll(self, net):
287 # create a new device with lctl
288 def newdev(self, attach, setup = ""):
293 quit""" % (attach, setup)
297 def cleanup(self, name, uuid):
306 def lovconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist):
310 lovconfig %s %d %d %d %s %s
311 quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist)
314 # ============================================================
315 # Various system-level functions
316 # (ideally moved to their own module)
318 # Run a command and return the output and status.
319 # stderr is sent to /dev/null, could use popen3 to
320 # save it if necessary
322 cmd = string.join(map(str,args))
324 if config.noexec(): return (0, [])
325 f = os.popen(cmd + ' 2>&1')
334 # Run a command in the background.
335 def run_daemon(*args):
336 cmd = string.join(map(str,args))
338 if config.noexec(): return 0
339 f = os.popen(cmd + ' 2>&1')
347 # Determine full path to use for an external command
348 # searches dirname(argv[0]) first, then PATH
350 syspath = string.split(os.environ['PATH'], ':')
351 cmdpath = os.path.dirname(sys.argv[0])
352 syspath.insert(0, cmdpath);
353 syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/'))
355 prog = os.path.join(d,cmd)
356 if os.access(prog, os.X_OK):
360 # Recursively look for file starting at base dir
361 def do_find_file(base, mod):
362 fullname = os.path.join(base, mod)
363 if os.access(fullname, os.R_OK):
365 for d in os.listdir(base):
366 dir = os.path.join(base,d)
367 if os.path.isdir(dir):
368 module = do_find_file(dir, mod)
372 def find_module(src_dir, modname):
373 mod = '%s.o' % (modname)
374 search = (src_dir + "/lustre", src_dir + "/portals/linux")
377 module = do_find_file(d, mod)
384 # is the path a block device?
391 return stat.S_ISBLK(s[stat.ST_MODE])
393 # build fs according to type
395 def mkfs(fstype, dev):
396 if(fstype in ('ext3', 'extN')):
397 mkfs = 'mkfs.ext2 -j -b 4096'
399 print 'unsupported fs type: ', fstype
400 if not is_block(dev):
404 (ret, out) = run (mkfs, force, dev)
406 panic("Unable to build fs:", dev)
407 # enable hash tree indexing on fs
409 htree = 'echo "feature FEATURE_C5" | debugfs -w'
410 (ret, out) = run (htree, dev)
412 panic("Unable to enable htree:", dev)
414 # some systems use /dev/loopN, some /dev/loop/N
418 if not os.access(loop + str(0), os.R_OK):
420 if not os.access(loop + str(0), os.R_OK):
421 panic ("can't access loop devices")
424 # find loop device assigned to thefile
427 for n in xrange(0, MAX_LOOP_DEVICES):
429 if os.access(dev, os.R_OK):
430 (stat, out) = run('losetup', dev)
431 if (out and stat == 0):
432 m = re.search(r'\((.*)\)', out[0])
433 if m and file == m.group(1):
439 # create file if necessary and assign the first free loop device
440 def init_loop(file, size, fstype):
441 dev = find_loop(file)
443 print 'WARNING file:', file, 'already mapped to', dev
445 if not os.access(file, os.R_OK | os.W_OK):
446 run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, file))
448 # find next free loop
449 for n in xrange(0, MAX_LOOP_DEVICES):
451 if os.access(dev, os.R_OK):
452 (stat, out) = run('losetup', dev)
454 run('losetup', dev, file)
457 print "out of loop devices"
459 print "out of loop devices"
462 # undo loop assignment
463 def clean_loop(file):
464 dev = find_loop(file)
466 ret, out = run('losetup -d', dev)
468 log('unable to clean loop device:', dev, 'for file:', file)
471 # initialize a block device if needed
472 def block_dev(dev, size, fstype, format):
473 if config.noexec(): return dev
474 if not is_block(dev):
475 dev = init_loop(dev, size, fstype)
476 if (format == 'yes'):
480 def get_local_address(net_type):
481 """Return the local address for the network type."""
483 if net_type == 'tcp':
485 host = socket.gethostname()
486 local = socket.gethostbyname(host)
487 elif net_type == 'elan':
488 # awk '/NodeId/ { print $2 }' '/proc/elan/device0/position'
490 fp = open('/proc/elan/device0/position', 'r')
491 lines = fp.readlines()
500 elif net_type == 'gm':
501 fixme("automatic local address for GM")
506 # ============================================================
507 # Classes to prepare and cleanup the various objects
510 """ Base class for the rest of the modules. The default cleanup method is
511 defined here, as well as some utilitiy funcs.
513 def __init__(self, tag_name, node):
515 self.tag_name = tag_name
516 self.name = node.getAttribute('name')
517 self.uuid = node.getAttribute('uuid')
518 self.kmodule_list = []
520 def info(self, *args):
521 msg = string.join(map(str,args))
522 print self.tag_name + ":", self.name, self.uuid, msg
525 """ default cleanup, used for most modules """
528 lctl.cleanup(self.name, self.uuid)
530 print "cleanup failed: ", self.name
532 def add_module(self, modname):
533 """Append a module to list of modules to load."""
534 self.kmodule_list.append(modname)
536 def mod_loaded(self, modname):
537 """Check if a module is already loaded. Look in /proc/modules for it."""
538 fp = open('/proc/modules')
539 lines = fp.readlines()
541 # please forgive my tired fingers for this one
542 ret = filter(lambda word, mod=modname: word == mod,
543 map(lambda line: string.split(line)[0], lines))
546 def load_module(self):
547 """Load all the modules in the list in the order they appear."""
548 for mod in self.kmodule_list:
549 # (rc, out) = run ('/sbin/lsmod | grep -s', mod)
550 if self.mod_loaded(mod) and not config.noexec():
552 log ('loading module:', mod)
554 module = find_module(config.src_dir(), mod)
556 panic('module not found:', mod)
557 (rc, out) = run('/sbin/insmod', module)
559 raise CommandError('insmod', out, rc)
561 (rc, out) = run('/sbin/modprobe', mod)
563 raise CommandError('modprobe', out, rc)
565 def cleanup_module(self):
566 """Unload the modules in the list in reverse order."""
567 rev = self.kmodule_list
570 log('unloading module:', mod)
573 run('/sbin/rmmod', mod)
576 class Network(Module):
577 def __init__(self,node):
578 Module.__init__(self, 'NETWORK', node)
579 self.net_type = node.getAttribute('type')
580 self.nid = getText(node, 'server', "")
581 self.port = int(getText(node, 'port', 0))
582 self.send_buf = int(getText(node, 'send_buf', 0))
583 self.read_buf = int(getText(node, 'read_buf', 0))
584 if not self.nid or self.nid == '*':
585 self.nid = get_local_address(self.net_type)
587 self.add_module('portals')
588 if self.net_type == 'tcp':
589 self.add_module('ksocknal')
590 if self.net_type == 'elan':
591 self.add_module('kqswnal')
592 if self.net_type == 'gm':
593 self.add_module('kgmnal')
594 self.add_module('obdclass')
595 self.add_module('ptlrpc')
598 self.info(self.net_type, self.nid, self.port)
599 if self.net_type == 'tcp':
600 ret = run_daemon(TCP_ACCEPTOR, self.port)
602 raise CommandError(TCP_ACCEPTOR, 'failed', ret)
603 lctl.network(self.net_type, self.nid)
604 lctl.newdev(attach = "ptlrpc RPCDEV")
607 self.info(self.net_type, self.nid, self.port)
609 lctl.cleanup("RPCDEV", "")
610 lctl.disconnectAll(self.net_type)
612 print "cleanup failed: ", self.name
613 if self.net_type == 'tcp':
614 # yikes, this ugly! need to save pid in /var/something
615 run("killall acceptor")
618 def __init__(self,node):
619 Module.__init__(self, 'LDLM', node)
620 self.add_module('ldlm')
623 lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid),
627 def __init__(self,node):
628 Module.__init__(self, 'LOV', node)
629 devs = node.getElementsByTagName('devices')[0]
630 self.stripe_sz = int(devs.getAttribute('stripesize'))
631 self.stripe_off = int(devs.getAttribute('stripeoffset'))
632 self.pattern = int(devs.getAttribute('pattern'))
633 mdsref = node.getElementsByTagName('mds_ref')[0]
634 self.mdsuuid = mdsref.getAttribute('uuidref')
635 mds= lookup(node.parentNode, self.mdsuuid)
636 self.mdsname = getName(mds)
639 for child in devs.childNodes:
640 if child.nodeName == 'osc_ref':
641 devlist = devlist + child.getAttribute('uuidref') + " "
642 stripe_cnt = stripe_cnt + 1
643 self.devlist = devlist
644 self.stripe_cnt = stripe_cnt
645 self.add_module('osc')
646 self.add_module('lov')
649 self.info(self.mdsuuid, self.stripe_cnt, self.stripe_sz, self.stripe_off, self.pattern,
650 self.devlist, self.mdsname)
651 lctl.lovconfig(self.uuid, self.mdsname, self.stripe_cnt,
652 self.stripe_sz, self.stripe_off, self.pattern,
659 def __init__(self,node):
660 Module.__init__(self, 'MDS', node)
661 self.devname, self.size = getDevice(node)
662 self.fstype = getText(node, 'fstype')
663 self.format = getText(node, 'autoformat', "no")
664 if self.fstype == 'extN':
665 self.add_module('extN')
666 self.add_module('mds')
667 self.add_module('mds_%s' % (self.fstype))
670 self.info(self.devname, self.fstype, self.format)
671 blkdev = block_dev(self.devname, self.size, self.fstype, self.format)
672 lctl.newdev(attach="mds %s %s" % (self.name, self.uuid),
673 setup ="%s %s" %(blkdev, self.fstype))
676 clean_loop(self.devname)
679 def __init__(self,node):
680 Module.__init__(self, 'MDC', node)
681 ref = node.getElementsByTagName('mds_ref')[0]
682 self.mds_uuid = ref.getAttribute('uuidref')
683 self.add_module('mdc')
686 self.info(self.mds_uuid)
687 mds = lookup(self.dom_node.parentNode, self.mds_uuid)
689 panic(self.mdsuuid, "not found.")
690 net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
692 lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
693 lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid),
694 setup ="%s %s" %(self.mds_uuid, srv.uuid))
697 self.info(self.mds_uuid)
698 net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
701 lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
702 lctl.cleanup(self.name, self.uuid)
704 print "cleanup failed: ", self.name
707 def __init__(self, node):
708 Module.__init__(self, 'OBD', node)
709 self.obdtype = node.getAttribute('type')
710 self.devname, self.size = getDevice(node)
711 self.fstype = getText(node, 'fstype')
712 self.format = getText(node, 'autoformat', 'yes')
713 if self.fstype == 'extN':
714 self.add_module('extN')
715 self.add_module(self.obdtype)
717 # need to check /proc/mounts and /etc/mtab before
718 # formatting anything.
719 # FIXME: check if device is already formatted.
721 self.info(self.obdtype, self.devname, self.size, self.fstype, self.format)
722 blkdev = block_dev(self.devname, self.size, self.fstype, self.format)
723 lctl.newdev(attach="%s %s %s" % (self.obdtype, self.name, self.uuid),
724 setup ="%s %s" %(blkdev, self.fstype))
727 clean_loop(self.devname)
730 def __init__(self,node):
731 Module.__init__(self, 'OST', node)
732 ref = node.getElementsByTagName('obd_ref')[0]
733 self.obd_uuid = ref.getAttribute('uuidref')
734 self.add_module('ost')
737 self.info(self.obd_uuid)
738 lctl.newdev(attach="ost %s %s" % (self.name, self.uuid),
739 setup ="%s" % (self.obd_uuid))
742 def __init__(self,node):
743 Module.__init__(self, 'OSC', node)
744 ref = node.getElementsByTagName('obd_ref')[0]
745 self.obd_uuid = ref.getAttribute('uuidref')
746 ref = node.getElementsByTagName('ost_ref')[0]
747 self.ost_uuid = ref.getAttribute('uuidref')
748 self.add_module('osc')
751 self.info(self.obd_uuid, self.ost_uuid)
752 net = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
754 lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
755 lctl.newdev(attach="osc %s %s" % (self.name, self.uuid),
756 setup ="%s %s" %(self.obd_uuid, srv.uuid))
759 self.info(self.obd_uuid, self.ost_uuid)
760 net_uuid = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
761 srv = Network(net_uuid)
763 lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
764 lctl.cleanup(self.name, self.uuid)
766 print "cleanup failed: ", self.name
768 class Mountpoint(Module):
769 def __init__(self,node):
770 Module.__init__(self, 'MTPT', node)
771 self.path = getText(node, 'path')
772 ref = node.getElementsByTagName('mdc_ref')[0]
773 self.mdc_uuid = ref.getAttribute('uuidref')
774 ref = node.getElementsByTagName('osc_ref')[0]
775 self.lov_uuid = ref.getAttribute('uuidref')
776 self.add_module('osc')
777 self.add_module('llite')
780 l = lookup(self.dom_node.parentNode, self.lov_uuid)
781 if l.nodeName == 'lov':
783 for osc_uuid in string.split(lov.devlist):
784 osc = lookup(self.dom_node.parentNode, osc_uuid)
789 panic('osc not found:', osc_uuid)
790 lctl.newdev(attach="lov %s %s" % (lov.name, lov.uuid),
791 setup ="%s" % (self.mdc_uuid))
796 self.info(self.path, self.mdc_uuid,self.lov_uuid)
797 cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \
798 (self.lov_uuid, self.mdc_uuid, self.path)
799 run("mkdir", self.path)
802 panic("mount failed:", self.path)
804 self.info(self.path, self.mdc_uuid,self.lov_uuid)
805 run("umount", self.path)
806 l = lookup(self.dom_node.parentNode, self.lov_uuid)
807 if l.nodeName == 'lov':
809 for osc_uuid in string.split(lov.devlist):
810 osc = lookup(self.dom_node.parentNode, osc_uuid)
815 panic('osc not found:', osc_uuid)
821 # ============================================================
822 # XML processing and query
823 # TODO: Change query funcs to use XPath, which is muc cleaner
826 dev = obd.getElementsByTagName('device')[0]
829 size = int(dev.getAttribute('size'))
832 return dev.firstChild.data, size
834 # Get the text content from the first matching child
835 def getText(node, tag, default=""):
836 list = node.getElementsByTagName(tag)
840 return node.firstChild.data
844 def get_ost_net(node, uuid):
845 ost = lookup(node, uuid)
846 list = ost.getElementsByTagName('network_ref')
848 uuid = list[0].getAttribute('uuidref')
851 return lookup(node, uuid)
853 def lookup(node, uuid):
854 for n in node.childNodes:
855 if n.nodeType == n.ELEMENT_NODE:
856 if getUUID(n) == uuid:
863 # Get name attribute of node
865 return node.getAttribute('name')
868 return node.getAttribute('uuidref')
870 # Get name attribute of node
872 return node.getAttribute('uuid')
874 # the tag name is the service type
875 # fixme: this should do some checks to make sure the node is a service
876 def getServiceType(node):
880 # determine what "level" a particular node is at.
881 # the order of iniitailization is based on level. objects
882 # are assigned a level based on type:
883 # net,devices,ldlm:1, obd, mdd:2 mds,ost:3 osc,mdc:4 mounts:5
884 def getServiceLevel(node):
885 type = getServiceType(node)
886 if type in ('network',):
888 if type in ('device', 'ldlm'):
890 elif type in ('obd', 'mdd'):
892 elif type in ('mds','ost'):
894 elif type in ('mdc','osc'):
896 elif type in ('lov',):
898 elif type in ('mountpoint',):
903 # return list of services in a profile. list is a list of tuples
905 def getServices(lustreNode, profileNode):
907 for n in profileNode.childNodes:
908 if n.nodeType == n.ELEMENT_NODE:
909 servNode = lookup(lustreNode, getRef(n))
912 panic('service not found: ' + getRef(n))
913 level = getServiceLevel(servNode)
914 list.append((level, servNode))
918 def getByName(lustreNode, tag, name):
919 ndList = lustreNode.getElementsByTagName(tag)
921 if getName(nd) == name:
926 # ============================================================
929 def startService(node, clean_flag, module_flag):
930 type = getServiceType(node)
931 debug('Service:', type, getName(node), getUUID(node))
932 # there must be a more dynamic way of doing this...
938 elif type == 'network':
950 elif type == 'mountpoint':
953 panic ("unknown service type:", type)
971 # Prepare the system to run lustre using a particular profile
972 # in a the configuration.
973 # * load & the modules
974 # * setup networking for the current node
975 # * make sure partitions are in place and prepared
976 # * initialize devices with lctl
977 # Levels is important, and needs to be enforced.
978 def startProfile(lustreNode, profileNode, clean_flag, module_flag):
980 panic("profile:", profile, "not found.")
981 services = getServices(lustreNode, profileNode)
985 startService(s[1], clean_flag, module_flag)
989 def doHost(lustreNode, hosts, clean_flag):
992 node = getByName(lustreNode, 'node', h)
997 print 'No host entry found.'
1000 # Two step process: (1) load modules, (2) setup lustre
1001 # if not cleaning, load modules first.
1002 module_flag = not clean_flag
1003 reflist = node.getElementsByTagName('profile')
1004 for profile in reflist:
1005 startProfile(lustreNode, profile, clean_flag, module_flag)
1009 script = config.gdb_script()
1010 run(lctl.lctl, ' modules >', script)
1012 # dump /tmp/ogdb and sleep/pause here
1013 log ("The GDB module script is in", script)
1016 module_flag = not module_flag
1017 for profile in reflist:
1018 startProfile(lustreNode, profile, clean_flag, module_flag)
1020 # Command line processing
1022 def parse_cmdline(argv):
1024 long_opts = ["ldap", "reformat", "lustre=", "verbose", "gdb",
1025 "portals=", "makeldiff", "cleanup", "noexec",
1026 "help", "node=", "get=", "nomod", "nosetup"]
1030 opts, args = getopt.getopt(argv, short_opts, long_opts)
1031 except getopt.GetoptError:
1036 if o in ("-h", "--help"):
1038 if o in ("-d","--cleanup"):
1040 if o in ("-v", "--verbose"):
1042 if o in ("-n", "--noexec"):
1045 if o == "--portals":
1049 if o == "--reformat":
1059 if o == "--nosetup":
1067 s = urllib.urlopen(url)
1073 def setupModulePath(cmd):
1074 base = os.path.dirname(cmd)
1075 if os.access(base+"/Makefile", os.R_OK):
1076 config.src_dir(base + "/../../")
1079 debug("debug path: ", config.debug_path())
1083 fp = open('/proc/sys/portals/debug_path', 'w')
1084 fp.write(config.debug_path())
1091 if not os.access('/dev/portals', os.R_OK):
1092 run('mknod /dev/portals c 10 240')
1093 if not os.access('/dev/obd', os.R_OK):
1094 run('mknod /dev/obd c 10 241')
1096 # Initialize or shutdown lustre according to a configuration file
1097 # * prepare the system for lustre
1098 # * configure devices with lctl
1099 # Shutdown does steps in reverse
1102 global TCP_ACCEPTOR, lctl
1103 args = parse_cmdline(sys.argv[1:])
1105 if not os.access(args[0], os.R_OK | os.W_OK):
1106 print 'File not found:', args[0]
1108 dom = xml.dom.minidom.parse(args[0])
1110 xmldata = fetch(config.url())
1111 dom = xml.dom.minidom.parseString(xmldata)
1117 node_list.append(config.node())
1119 host = socket.gethostname()
1121 node_list.append(host)
1122 node_list.append('localhost')
1123 debug("configuring for host: ", node_list)
1125 TCP_ACCEPTOR = find_prog('acceptor')
1126 if not TCP_ACCEPTOR:
1128 TCP_ACCEPTOR = 'acceptor'
1129 debug('! acceptor not found')
1131 panic('acceptor not found')
1133 lctl = LCTLInterface('lctl')
1135 setupModulePath(sys.argv[0])
1137 doHost(dom.documentElement, node_list, config.cleanup())
1139 if __name__ == "__main__":
1142 except RuntimeError:
1144 except CommandError, e: