3 # Copyright (C) 2002 Cluster File Systems, Inc.
4 # Author: Robert Read <rread@clusterfs.com>
5 # This file is part of Lustre, http://www.lustre.org.
7 # Lustre is free software; you can redistribute it and/or
8 # modify it under the terms of version 2 of the GNU General Public
9 # License as published by the Free Software Foundation.
11 # Lustre is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Lustre; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 # For all the OST/MDSs that are primary on the --primary node, set
22 # them to be active on --active if that OST is available on --active.
24 # Make the active node the active node for all devices it shares with the
25 # old. The bulk of this code is for figuring out which devices to
26 # change, and what to change them to.
28 # XXX add error checking
29 # XXX make this code less ugly
31 import sys, getopt, types
34 from stat import S_IROTH, S_IRGRP
35 PYMOD_DIR = "/usr/lib/lustre/python"
37 def development_mode():
38 base = os.path.dirname(sys.argv[0])
39 if os.access(base+"/Makefile.am", os.R_OK):
43 if not development_mode():
44 sys.path.append(PYMOD_DIR)
47 PARAM = Lustre.Options.PARAM
50 ('ldapurl',"LDAP server URL", PARAM, "ldap://localhost"),
51 ('config', "Cluster config name used for LDAP query", PARAM),
52 ('group', "The group of devices to update", PARAM),
53 ('active', "The active node name", PARAM),
54 ('pwfile', "File containing password", PARAM),
58 msg = string.join(map(str,args))
62 cl = Lustre.Options("lactive","", lactive_options)
63 config, args = cl.parse(sys.argv[1:])
65 if not (config.group or config.active):
66 fatal("Must specify both group and active node.")
69 fatal("Missing config")
73 pwperm = os.stat(config.pwfile)[0]
74 pwreadable = pwperm & (S_IRGRP | S_IROTH)
76 if pwreadable == (S_IRGRP | S_IROTH):
77 readable_by = "group and others"
78 elif pwreadable == S_IRGRP:
81 readable_by = "others"
82 print "WARNING: Password file %s is readable by %s" % (
83 config.pwfile, readable_by)
85 pwfile = open(config.pwfile, "r")
86 pw = string.strip(pwfile.readline())
89 fatal("Can't read secret from pwfile %s: %s" % (config.pwfile, e))
91 print "no pwfile specified, binding anonymously"
94 base = "config=%s,fs=lustre" % (config.config,)
95 db = Lustre.LustreDB_LDAP('', {}, base=base, pw = pw, url = config.ldapurl)
97 active_node = db.lookup_name(config.active)
99 fatal(config.active, "node not found in database.")
101 devices = db.get_group(config.group)
103 fatal("no devices found for group", config.group)
105 # for all devices in group
106 # lookup device in active node
107 # update the active device
108 for tgtuuid in devices:
109 active_uuid = db.get_active_dev(tgtuuid)
110 new_active_uuid = active_node.get_tgt_dev(tgtuuid)
111 if active_uuid != new_active_uuid:
112 print ("%s: changing active %s to %s:%s"
113 % (tgtuuid, active_uuid,
114 config.active, new_active_uuid))
115 db.update_active(tgtuuid, new_active_uuid)