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))
153 if not config.noexec():
154 raise LconfError(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 class LconfError (exceptions.Exception):
195 def __init__(self, args):
199 # ============================================================
200 # handle lctl interface
203 Manage communication with lctl
206 def __init__(self, cmd):
208 Initialize close by finding the lctl binary.
210 self.lctl = find_prog(cmd)
213 debug('! lctl not found')
216 raise CommandError('lctl', "unable to find lctl binary.")
221 the cmds are written to stdin of lctl
222 lctl doesn't return errors when run in script mode, so
224 should modify command line to accept multiple commands, or
225 create complex command line options
227 debug("+", self.lctl, cmds)
228 if config.noexec(): return (0, [])
229 p = popen2.Popen3(self.lctl, 1)
230 p.tochild.write(cmds + "\n")
232 out = p.fromchild.readlines()
233 err = p.childerr.readlines()
236 raise CommandError(self.lctl, err, ret)
240 def network(self, net, nid):
241 """ initialized network and add "self" """
242 # Idea: "mynid" could be used for all network types to add "self," and then
243 # this special case would be gone and the "self" hack would be hidden.
249 quit""" % (net, nid, nid)
258 # create a new connection
259 def connect(self, net, nid, port, servuuid, send_buf, read_buf):
260 # XXX: buf size params not used yet
265 quit""" % (net, nid, port, servuuid, nid)
268 # create a new connection
269 def add_route(self, net, to, via):
274 # disconnect one connection
275 def disconnect(self, net, nid, port, servuuid):
280 quit""" % (net, nid, servuuid)
283 # disconnect all connections
284 def disconnectAll(self, net):
292 # create a new device with lctl
293 def newdev(self, attach, setup = ""):
298 quit""" % (attach, setup)
302 def cleanup(self, name, uuid):
311 def lovconfig(self, uuid, mdsuuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist):
315 lovconfig %s %d %d %d %s %s
316 quit""" % (mdsuuid, uuid, stripe_cnt, stripe_sz, stripe_off, pattern, devlist)
319 # ============================================================
320 # Various system-level functions
321 # (ideally moved to their own module)
323 # Run a command and return the output and status.
324 # stderr is sent to /dev/null, could use popen3 to
325 # save it if necessary
327 cmd = string.join(map(str,args))
329 if config.noexec(): return (0, [])
330 f = os.popen(cmd + ' 2>&1')
339 # Run a command in the background.
340 def run_daemon(*args):
341 cmd = string.join(map(str,args))
343 if config.noexec(): return 0
344 f = os.popen(cmd + ' 2>&1')
352 # Determine full path to use for an external command
353 # searches dirname(argv[0]) first, then PATH
355 syspath = string.split(os.environ['PATH'], ':')
356 cmdpath = os.path.dirname(sys.argv[0])
357 syspath.insert(0, cmdpath);
358 syspath.insert(0, os.path.join(cmdpath, '../../portals/linux/utils/'))
360 prog = os.path.join(d,cmd)
361 if os.access(prog, os.X_OK):
365 # Recursively look for file starting at base dir
366 def do_find_file(base, mod):
367 fullname = os.path.join(base, mod)
368 if os.access(fullname, os.R_OK):
370 for d in os.listdir(base):
371 dir = os.path.join(base,d)
372 if os.path.isdir(dir):
373 module = do_find_file(dir, mod)
377 def find_module(src_dir, modname):
378 mod = '%s.o' % (modname)
379 search = (src_dir + "/lustre", src_dir + "/portals/linux")
382 module = do_find_file(d, mod)
389 # is the path a block device?
396 return stat.S_ISBLK(s[stat.ST_MODE])
398 # build fs according to type
400 def mkfs(fstype, dev):
401 if(fstype in ('ext3', 'extN')):
402 mkfs = 'mkfs.ext2 -j -b 4096'
404 print 'unsupported fs type: ', fstype
405 if not is_block(dev):
409 (ret, out) = run (mkfs, force, dev)
411 panic("Unable to build fs:", dev)
412 # enable hash tree indexing on fs
414 htree = 'echo "feature FEATURE_C5" | debugfs -w'
415 (ret, out) = run (htree, dev)
417 panic("Unable to enable htree:", dev)
419 # some systems use /dev/loopN, some /dev/loop/N
423 if not os.access(loop + str(0), os.R_OK):
425 if not os.access(loop + str(0), os.R_OK):
426 panic ("can't access loop devices")
429 # find loop device assigned to thefile
432 for n in xrange(0, MAX_LOOP_DEVICES):
434 if os.access(dev, os.R_OK):
435 (stat, out) = run('losetup', dev)
436 if (out and stat == 0):
437 m = re.search(r'\((.*)\)', out[0])
438 if m and file == m.group(1):
444 # create file if necessary and assign the first free loop device
445 def init_loop(file, size, fstype):
446 dev = find_loop(file)
448 print 'WARNING file:', file, 'already mapped to', dev
450 if not os.access(file, os.R_OK | os.W_OK):
451 run("dd if=/dev/zero bs=1k count=0 seek=%d of=%s" %(size, file))
453 # find next free loop
454 for n in xrange(0, MAX_LOOP_DEVICES):
456 if os.access(dev, os.R_OK):
457 (stat, out) = run('losetup', dev)
459 run('losetup', dev, file)
462 print "out of loop devices"
464 print "out of loop devices"
467 # undo loop assignment
468 def clean_loop(file):
469 dev = find_loop(file)
471 ret, out = run('losetup -d', dev)
473 log('unable to clean loop device:', dev, 'for file:', file)
476 # initialize a block device if needed
477 def block_dev(dev, size, fstype, format):
478 if config.noexec(): return dev
479 if not is_block(dev):
480 dev = init_loop(dev, size, fstype)
481 if (format == 'yes'):
485 def get_local_address(net_type):
486 """Return the local address for the network type."""
488 if net_type == 'tcp':
490 host = socket.gethostname()
491 local = socket.gethostbyname(host)
492 elif net_type == 'elan':
493 # awk '/NodeId/ { print $2 }' '/proc/elan/device0/position'
495 fp = open('/proc/elan/device0/position', 'r')
496 lines = fp.readlines()
505 elif net_type == 'gm':
506 fixme("automatic local address for GM")
511 # ============================================================
512 # Classes to prepare and cleanup the various objects
515 """ Base class for the rest of the modules. The default cleanup method is
516 defined here, as well as some utilitiy funcs.
518 def __init__(self, tag_name, node):
520 self.tag_name = tag_name
521 self.name = node.getAttribute('name')
522 self.uuid = node.getAttribute('uuid')
523 self.kmodule_list = []
525 def info(self, *args):
526 msg = string.join(map(str,args))
527 print self.tag_name + ":", self.name, self.uuid, msg
530 """ default cleanup, used for most modules """
533 lctl.cleanup(self.name, self.uuid)
535 print "cleanup failed: ", self.name
537 def add_module(self, modname):
538 """Append a module to list of modules to load."""
539 self.kmodule_list.append(modname)
541 def mod_loaded(self, modname):
542 """Check if a module is already loaded. Look in /proc/modules for it."""
543 fp = open('/proc/modules')
544 lines = fp.readlines()
546 # please forgive my tired fingers for this one
547 ret = filter(lambda word, mod=modname: word == mod,
548 map(lambda line: string.split(line)[0], lines))
551 def load_module(self):
552 """Load all the modules in the list in the order they appear."""
553 for mod in self.kmodule_list:
554 # (rc, out) = run ('/sbin/lsmod | grep -s', mod)
555 if self.mod_loaded(mod) and not config.noexec():
557 log ('loading module:', mod)
559 module = find_module(config.src_dir(), mod)
561 panic('module not found:', mod)
562 (rc, out) = run('/sbin/insmod', module)
564 raise CommandError('insmod', out, rc)
566 (rc, out) = run('/sbin/modprobe', mod)
568 raise CommandError('modprobe', out, rc)
570 def cleanup_module(self):
571 """Unload the modules in the list in reverse order."""
572 rev = self.kmodule_list
575 log('unloading module:', mod)
578 (rc, out) = run('/sbin/rmmod', mod)
580 log('! unable to unload module:', mod)
584 class Network(Module):
585 def __init__(self,node):
586 Module.__init__(self, 'NETWORK', node)
587 self.net_type = node.getAttribute('type')
588 self.nid = getText(node, 'server', '*')
589 self.port = int(getText(node, 'port', 0))
590 self.send_buf = int(getText(node, 'send_buf', 0))
591 self.read_buf = int(getText(node, 'read_buf', 0))
593 self.nid = get_local_address(self.net_type)
595 panic("unable to set nid for", self.net_type)
597 self.add_module('portals')
598 if self.net_type == 'tcp':
599 self.add_module('ksocknal')
600 if self.net_type == 'elan':
601 self.add_module('kqswnal')
602 if self.net_type == 'gm':
603 self.add_module('kgmnal')
604 self.add_module('obdclass')
605 self.add_module('ptlrpc')
608 self.info(self.net_type, self.nid, self.port)
609 if self.net_type == 'tcp':
610 ret = run_daemon(TCP_ACCEPTOR, self.port)
612 raise CommandError(TCP_ACCEPTOR, 'failed', ret)
613 lctl.network(self.net_type, self.nid)
614 lctl.newdev(attach = "ptlrpc RPCDEV")
617 self.info(self.net_type, self.nid, self.port)
619 lctl.cleanup("RPCDEV", "")
620 lctl.disconnectAll(self.net_type)
622 print "cleanup failed: ", self.name
623 if self.net_type == 'tcp':
624 # yikes, this ugly! need to save pid in /var/something
625 run("killall acceptor")
628 def __init__(self,node):
629 Module.__init__(self, 'LDLM', node)
630 self.add_module('ldlm')
633 lctl.newdev(attach="ldlm %s %s" % (self.name, self.uuid),
637 def __init__(self,node):
638 Module.__init__(self, 'LOV', node)
639 devs = node.getElementsByTagName('devices')[0]
640 self.stripe_sz = int(devs.getAttribute('stripesize'))
641 self.stripe_off = int(devs.getAttribute('stripeoffset'))
642 self.pattern = int(devs.getAttribute('pattern'))
643 mdsref = node.getElementsByTagName('mds_ref')[0]
644 self.mdsuuid = mdsref.getAttribute('uuidref')
645 mds= lookup(node.parentNode, self.mdsuuid)
646 self.mdsname = getName(mds)
649 for child in devs.childNodes:
650 if child.nodeName == 'osc_ref':
651 devlist = devlist + child.getAttribute('uuidref') + " "
652 stripe_cnt = stripe_cnt + 1
653 self.devlist = devlist
654 self.stripe_cnt = stripe_cnt
655 self.add_module('osc')
656 self.add_module('lov')
659 self.info(self.mdsuuid, self.stripe_cnt, self.stripe_sz, self.stripe_off, self.pattern,
660 self.devlist, self.mdsname)
661 lctl.lovconfig(self.uuid, self.mdsname, self.stripe_cnt,
662 self.stripe_sz, self.stripe_off, self.pattern,
669 def __init__(self,node):
670 Module.__init__(self, 'MDS', node)
671 self.devname, self.size = getDevice(node)
672 self.fstype = getText(node, 'fstype')
673 self.format = getText(node, 'autoformat', "no")
674 if self.fstype == 'extN':
675 self.add_module('extN')
676 self.add_module('mds')
677 self.add_module('mds_%s' % (self.fstype))
680 self.info(self.devname, self.fstype, self.format)
681 blkdev = block_dev(self.devname, self.size, self.fstype, self.format)
682 lctl.newdev(attach="mds %s %s" % (self.name, self.uuid),
683 setup ="%s %s" %(blkdev, self.fstype))
686 clean_loop(self.devname)
689 def __init__(self,node):
690 Module.__init__(self, 'MDC', node)
691 ref = node.getElementsByTagName('mds_ref')[0]
692 self.mds_uuid = ref.getAttribute('uuidref')
693 self.add_module('mdc')
696 self.info(self.mds_uuid)
697 mds = lookup(self.dom_node.parentNode, self.mds_uuid)
699 panic(self.mdsuuid, "not found.")
700 net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
702 lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
703 lctl.newdev(attach="mdc %s %s" % (self.name, self.uuid),
704 setup ="%s %s" %(self.mds_uuid, srv.uuid))
707 self.info(self.mds_uuid)
708 net = get_ost_net(self.dom_node.parentNode, self.mds_uuid)
711 lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
713 print "disconnect failed: ", self.name
715 lctl.cleanup(self.name, self.uuid)
717 print "cleanup failed: ", self.name
720 def __init__(self, node):
721 Module.__init__(self, 'OBD', node)
722 self.obdtype = node.getAttribute('type')
723 self.devname, self.size = getDevice(node)
724 self.fstype = getText(node, 'fstype')
725 self.format = getText(node, 'autoformat', 'yes')
726 if self.fstype == 'extN':
727 self.add_module('extN')
728 self.add_module(self.obdtype)
730 # need to check /proc/mounts and /etc/mtab before
731 # formatting anything.
732 # FIXME: check if device is already formatted.
734 self.info(self.obdtype, self.devname, self.size, self.fstype, self.format)
735 if self.obdtype == 'obdecho':
738 blkdev = block_dev(self.devname, self.size, self.fstype, self.format)
739 lctl.newdev(attach="%s %s %s" % (self.obdtype, self.name, self.uuid),
740 setup ="%s %s" %(blkdev, self.fstype))
743 if not self.obdtype == 'obdecho':
744 clean_loop(self.devname)
747 def __init__(self,node):
748 Module.__init__(self, 'OST', node)
749 ref = node.getElementsByTagName('obd_ref')[0]
750 self.obd_uuid = ref.getAttribute('uuidref')
751 self.add_module('ost')
754 self.info(self.obd_uuid)
755 lctl.newdev(attach="ost %s %s" % (self.name, self.uuid),
756 setup ="%s" % (self.obd_uuid))
759 def __init__(self,node):
760 Module.__init__(self, 'OSC', node)
761 ref = node.getElementsByTagName('obd_ref')[0]
762 self.obd_uuid = ref.getAttribute('uuidref')
763 ref = node.getElementsByTagName('ost_ref')[0]
764 self.ost_uuid = ref.getAttribute('uuidref')
765 self.add_module('osc')
768 self.info(self.obd_uuid, self.ost_uuid)
769 net = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
771 lctl.connect(srv.net_type, srv.nid, srv.port, srv.uuid, srv.send_buf, srv.read_buf)
772 lctl.newdev(attach="osc %s %s" % (self.name, self.uuid),
773 setup ="%s %s" %(self.obd_uuid, srv.uuid))
776 self.info(self.obd_uuid, self.ost_uuid)
777 net_uuid = get_ost_net(self.dom_node.parentNode, self.ost_uuid)
778 srv = Network(net_uuid)
780 lctl.disconnect(srv.net_type, srv.nid, srv.port, srv.uuid)
782 print "disconnect failed: ", self.name
784 lctl.cleanup(self.name, self.uuid)
786 print "cleanup failed: ", self.name
788 class Mountpoint(Module):
789 def __init__(self,node):
790 Module.__init__(self, 'MTPT', node)
791 self.path = getText(node, 'path')
792 ref = node.getElementsByTagName('mdc_ref')[0]
793 self.mdc_uuid = ref.getAttribute('uuidref')
794 ref = node.getElementsByTagName('osc_ref')[0]
795 self.lov_uuid = ref.getAttribute('uuidref')
796 self.add_module('osc')
797 self.add_module('llite')
800 l = lookup(self.dom_node.parentNode, self.lov_uuid)
801 if l.nodeName == 'lov':
803 for osc_uuid in string.split(lov.devlist):
804 osc = lookup(self.dom_node.parentNode, osc_uuid)
809 panic('osc not found:', osc_uuid)
810 lctl.newdev(attach="lov %s %s" % (lov.name, lov.uuid),
811 setup ="%s" % (self.mdc_uuid))
816 self.info(self.path, self.mdc_uuid,self.lov_uuid)
817 cmd = "mount -t lustre_lite -o osc=%s,mdc=%s none %s" % \
818 (self.lov_uuid, self.mdc_uuid, self.path)
819 run("mkdir", self.path)
822 panic("mount failed:", self.path)
824 self.info(self.path, self.mdc_uuid,self.lov_uuid)
825 run("umount", self.path)
826 l = lookup(self.dom_node.parentNode, self.lov_uuid)
827 if l.nodeName == 'lov':
829 for osc_uuid in string.split(lov.devlist):
830 osc = lookup(self.dom_node.parentNode, osc_uuid)
835 panic('osc not found:', osc_uuid)
841 # ============================================================
842 # XML processing and query
843 # TODO: Change query funcs to use XPath, which is muc cleaner
846 list = obd.getElementsByTagName('device')
851 size = int(dev.getAttribute('size'))
854 return dev.firstChild.data, size
857 # Get the text content from the first matching child
858 # If there is no content (or it is all whitespace), return
860 def getText(node, tag, default=""):
861 list = node.getElementsByTagName(tag)
866 txt = string.strip(node.firstChild.data)
871 def get_ost_net(node, uuid):
872 ost = lookup(node, uuid)
873 list = ost.getElementsByTagName('network_ref')
875 uuid = list[0].getAttribute('uuidref')
878 return lookup(node, uuid)
880 def lookup(node, uuid):
881 for n in node.childNodes:
882 if n.nodeType == n.ELEMENT_NODE:
883 if getUUID(n) == uuid:
890 # Get name attribute of node
892 return node.getAttribute('name')
895 return node.getAttribute('uuidref')
897 # Get name attribute of node
899 return node.getAttribute('uuid')
901 # the tag name is the service type
902 # fixme: this should do some checks to make sure the node is a service
903 def getServiceType(node):
907 # determine what "level" a particular node is at.
908 # the order of iniitailization is based on level. objects
909 # are assigned a level based on type:
910 # net,devices,ldlm:1, obd, mdd:2 mds,ost:3 osc,mdc:4 mounts:5
911 def getServiceLevel(node):
912 type = getServiceType(node)
913 if type in ('network',):
915 if type in ('device', 'ldlm'):
917 elif type in ('obd', 'mdd'):
919 elif type in ('mds','ost'):
921 elif type in ('mdc','osc'):
923 elif type in ('lov',):
925 elif type in ('mountpoint',):
930 # return list of services in a profile. list is a list of tuples
932 def getServices(lustreNode, profileNode):
934 for n in profileNode.childNodes:
935 if n.nodeType == n.ELEMENT_NODE:
936 servNode = lookup(lustreNode, getRef(n))
939 panic('service not found: ' + getRef(n))
940 level = getServiceLevel(servNode)
941 list.append((level, servNode))
945 def getByName(lustreNode, tag, name):
946 ndList = lustreNode.getElementsByTagName(tag)
948 if getName(nd) == name:
953 # ============================================================
956 def startService(node, clean_flag, module_flag):
957 type = getServiceType(node)
958 debug('Service:', type, getName(node), getUUID(node))
959 # there must be a more dynamic way of doing this...
965 elif type == 'network':
977 elif type == 'mountpoint':
980 panic ("unknown service type:", type)
998 # Prepare the system to run lustre using a particular profile
999 # in a the configuration.
1000 # * load & the modules
1001 # * setup networking for the current node
1002 # * make sure partitions are in place and prepared
1003 # * initialize devices with lctl
1004 # Levels is important, and needs to be enforced.
1005 def startProfile(lustreNode, profileNode, clean_flag, module_flag):
1007 panic("profile:", profile, "not found.")
1008 services = getServices(lustreNode, profileNode)
1012 startService(s[1], clean_flag, module_flag)
1016 def doHost(lustreNode, hosts, clean_flag):
1019 node = getByName(lustreNode, 'node', h)
1024 print 'No host entry found.'
1027 # Two step process: (1) load modules, (2) setup lustre
1028 # if not cleaning, load modules first.
1029 module_flag = not clean_flag
1030 reflist = node.getElementsByTagName('profile')
1031 for profile in reflist:
1032 startProfile(lustreNode, profile, clean_flag, module_flag)
1036 script = config.gdb_script()
1037 run(lctl.lctl, ' modules >', script)
1039 # dump /tmp/ogdb and sleep/pause here
1040 log ("The GDB module script is in", script)
1043 module_flag = not module_flag
1044 for profile in reflist:
1045 startProfile(lustreNode, profile, clean_flag, module_flag)
1047 # Command line processing
1049 def parse_cmdline(argv):
1051 long_opts = ["ldap", "reformat", "lustre=", "verbose", "gdb",
1052 "portals=", "makeldiff", "cleanup", "noexec",
1053 "help", "node=", "get=", "nomod", "nosetup"]
1057 opts, args = getopt.getopt(argv, short_opts, long_opts)
1058 except getopt.error:
1063 if o in ("-h", "--help"):
1065 if o in ("-d","--cleanup"):
1067 if o in ("-v", "--verbose"):
1069 if o in ("-n", "--noexec"):
1072 if o == "--portals":
1076 if o == "--reformat":
1086 if o == "--nosetup":
1094 s = urllib.urlopen(url)
1100 def setupModulePath(cmd):
1101 base = os.path.dirname(cmd)
1102 if os.access(base+"/Makefile", os.R_OK):
1103 config.src_dir(base + "/../../")
1106 debug("debug path: ", config.debug_path())
1110 fp = open('/proc/sys/portals/debug_path', 'w')
1111 fp.write(config.debug_path())
1118 if not os.access('/dev/portals', os.R_OK):
1119 run('mknod /dev/portals c 10 240')
1120 if not os.access('/dev/obd', os.R_OK):
1121 run('mknod /dev/obd c 10 241')
1123 # Initialize or shutdown lustre according to a configuration file
1124 # * prepare the system for lustre
1125 # * configure devices with lctl
1126 # Shutdown does steps in reverse
1129 global TCP_ACCEPTOR, lctl
1130 args = parse_cmdline(sys.argv[1:])
1132 if not os.access(args[0], os.R_OK | os.W_OK):
1133 print 'File not found:', args[0]
1135 dom = xml.dom.minidom.parse(args[0])
1137 xmldata = fetch(config.url())
1138 dom = xml.dom.minidom.parseString(xmldata)
1144 node_list.append(config.node())
1146 host = socket.gethostname()
1148 node_list.append(host)
1149 node_list.append('localhost')
1150 debug("configuring for host: ", node_list)
1152 TCP_ACCEPTOR = find_prog('acceptor')
1153 if not TCP_ACCEPTOR:
1155 TCP_ACCEPTOR = 'acceptor'
1156 debug('! acceptor not found')
1158 panic('acceptor not found')
1160 lctl = LCTLInterface('lctl')
1162 setupModulePath(sys.argv[0])
1164 doHost(dom.documentElement, node_list, config.cleanup())
1166 if __name__ == "__main__":
1169 except LconfError, e:
1171 except CommandError, e: