+
+def magic_get_osc(db, rec, lov):
+ if lov:
+ lov_uuid = lov.get_uuid()
+ lov_name = lov.osc.fs_name
+ else:
+ lov_uuid = rec.getAttribute('lov_uuidref')
+ # FIXME: better way to find the mountpoint?
+ filesystems = db.root_node.getElementsByTagName('filesystem')
+ fsuuid = None
+ for fs in filesystems:
+ ref = fs.getElementsByTagName('obd_ref')
+ if ref[0].getAttribute('uuidref') == lov_uuid:
+ fsuuid = fs.getAttribute('uuid')
+ break
+
+ if not fsuuid:
+ panic("malformed xml: lov uuid '" + lov_uuid + "' referenced in 'add' record is not used by any filesystems.")
+
+ mtpts = db.root_node.getElementsByTagName('mountpoint')
+ lov_name = None
+ for fs in mtpts:
+ ref = fs.getElementsByTagName('filesystem_ref')
+ if ref[0].getAttribute('uuidref') == fsuuid:
+ lov_name = fs.getAttribute('name')
+ break
+
+ if not lov_name:
+ panic("malformed xml: 'add' record references lov uuid '" + lov_uuid + "', which references filesystem uuid '" + fsuuid + "', which does not reference a mountpoint.")
+
+ print "lov_uuid: " + lov_uuid + "; lov_name: " + lov_name
+
+ ost_uuid = rec.getAttribute('ost_uuidref')
+ obd = db.lookup(ost_uuid)
+
+ if not obd:
+ panic("malformed xml: 'add' record references ost uuid '" + ost_uuid + "' which cannot be found.")
+
+ osc = get_osc(obd, lov_uuid, lov_name)
+ if not osc:
+ panic('osc not found:', obd_uuid)
+ return osc
+
+# write logs for update records. sadly, logs of all types -- and updates in
+# particular -- are something of an afterthought. lconf needs rewritten with
+# these as core concepts. so this is a pretty big hack.
+def process_update_record(db, update, lov):
+ for rec in update.childNodes:
+ if rec.nodeType != rec.ELEMENT_NODE:
+ continue
+
+ log("found "+rec.nodeName+" record in update version " +
+ str(update.getAttribute('version')))
+
+ lov_uuid = rec.getAttribute('lov_uuidref')
+ ost_uuid = rec.getAttribute('ost_uuidref')
+ index = rec.getAttribute('index')
+ gen = rec.getAttribute('generation')
+
+ if not lov_uuid or not ost_uuid or not index or not gen:
+ panic("malformed xml: 'update' record requires lov_uuid, ost_uuid, index, and generation.")
+
+ if not lov:
+ tmplov = db.lookup(lov_uuid)
+ if not tmplov:
+ panic("malformed xml: 'delete' record contains lov UUID '" + lov_uuid + "', which cannot be located.")
+ lov_name = tmplov.getName()
+ else:
+ lov_name = lov.osc.name
+
+ # ------------------------------------------------------------- add
+ if rec.nodeName == 'add':
+ if config.cleanup:
+ lctl.lov_del_obd(lov_name, lov_uuid, ost_uuid, index, gen)
+ continue
+
+ osc = magic_get_osc(db, rec, lov)
+
+ try:
+ # Only ignore connect failures with --force, which
+ # isn't implemented here yet.
+ osc.prepare(ignore_connect_failure=0)
+ except CommandError, e:
+ print "Error preparing OSC %s\n" % osc.uuid
+ raise e
+
+ lctl.lov_add_obd(lov_name, lov_uuid, ost_uuid, index, gen)
+
+ # ------------------------------------------------------ deactivate
+ elif rec.nodeName == 'deactivate':
+ if config.cleanup:
+ continue
+
+ osc = magic_get_osc(db, rec, lov)
+
+ try:
+ osc.deactivate()
+ except CommandError, e:
+ print "Error deactivating OSC %s\n" % osc.uuid
+ raise e
+
+ # ---------------------------------------------------------- delete
+ elif rec.nodeName == 'delete':
+ if config.cleanup:
+ continue
+
+ osc = magic_get_osc(db, rec, lov)
+
+ try:
+ config.cleanup = 1
+ osc.cleanup()
+ config.cleanup = 0
+ except CommandError, e:
+ print "Error cleaning up OSC %s\n" % osc.uuid
+ raise e
+
+ lctl.lov_del_obd(lov_name, lov_uuid, ost_uuid, index, gen)
+
+def process_updates(db, log_device, log_name, lov = None):
+ updates = db.root_node.getElementsByTagName('update')
+ for u in updates:
+ if not u.childNodes:
+ log("ignoring empty update record (version " +
+ str(u.getAttribute('version')) + ")")
+ continue
+
+ version = u.getAttribute('version')
+ real_name = "%s-%s" % (log_name, version)
+ lctl.clear_log(log_device, real_name)
+ lctl.record(log_device, real_name)
+
+ process_update_record(db, u, lov)
+
+ lctl.end_record()
+