#!/usr/bin/python
-# Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks
+# Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
import argparse
import os
-import signal
import sys
import time
from ovs.db import types
import ovs.daemon
import ovs.db.idl
+import ovs.unixctl
+import ovs.unixctl.server
vlog = ovs.vlog.Vlog("ovs-xapi-sync")
session = None
-force_run = False
+flush_cache = False
+exiting = False
+
+
+def unixctl_exit(conn, unused_argv, unused_aux):
+ global exiting
+ exiting = True
+ conn.reply(None)
+
+
+def unixctl_flush_cache(conn, unused_argv, unused_aux):
+ global flush_cache
+ flush_cache = True
+ conn.reply(None)
# Set up a session to interact with XAPI.
" XAPI session could not be initialized" % br_name)
return None
- for n in session.xenapi.network.get_all():
- rec = session.xenapi.network.get_record(n)
- if rec['bridge'] == br_name:
- return rec
+ recs = session.xenapi.network.get_all_records_where('field "bridge"="%s"' % br_name)
+ if len(recs) > 0:
+ return recs.values()[0]
return None
def set_external_id(row, key, value):
+ row.verify("external_ids")
external_ids = row.external_ids
if set_or_delete(external_ids, key, value):
row.external_ids = external_ids
if fail_mode not in ['standalone', 'secure']:
fail_mode = 'standalone'
+ row.verify("fail_mode")
if row.fail_mode != fail_mode:
row.fail_mode = fail_mode
dib = rec['other_config'].get('vswitch-disable-in-band')
+ row.verify("other_config")
other_config = row.other_config
if dib and dib not in ['true', 'false']:
vlog.warn('"%s" isn\'t a valid setting for '
row.other_config = other_config
-def keep_table_columns(schema, table_name, columns):
- table = schema.tables.get(table_name)
- if not table:
- raise error.Error("schema has no %s table" % table_name)
-
- new_columns = {}
- for column_name in columns:
- column = table.columns.get(column_name)
- if not column:
- raise error.Error("%s table schema lacks %s column"
- % (table_name, column_name))
- new_columns[column_name] = column
- table.columns = new_columns
- return table
-
-
-def prune_schema(schema):
- new_tables = {}
- new_tables["Bridge"] = keep_table_columns(
- schema, "Bridge", ("name", "external_ids", "other_config",
- "fail_mode"))
- new_tables["Interface"] = keep_table_columns(
- schema, "Interface", ("name", "external_ids"))
- schema.tables = new_tables
-
-
-def handler(signum, _):
- global force_run
- if (signum == signal.SIGHUP):
- force_run = True
-
-
def main():
- global force_run
+ global flush_cache
parser = argparse.ArgumentParser()
parser.add_argument("database", metavar="DATABASE",
ovs.daemon.handle_args(args)
remote = args.database
- schema_file = "%s/vswitch.ovsschema" % ovs.dirs.PKGDATADIR
- schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schema_file))
- prune_schema(schema)
- idl = ovs.db.idl.Idl(remote, schema)
+ schema_helper = ovs.db.idl.SchemaHelper()
+ schema_helper.register_columns("Bridge", ["name", "external_ids",
+ "other_config", "fail_mode"])
+ schema_helper.register_columns("Interface", ["name", "external_ids"])
+ idl = ovs.db.idl.Idl(remote, schema_helper)
ovs.daemon.daemonize()
+ ovs.unixctl.command_register("exit", "", 0, 0, unixctl_exit, None)
+ ovs.unixctl.command_register("flush-cache", "", 0, 0, unixctl_flush_cache,
+ None)
+ error, unixctl_server = ovs.unixctl.server.UnixctlServer.create(None)
+ if error:
+ ovs.util.ovs_fatal(error, "could not create unixctl server", vlog)
+
# This daemon is usually started before XAPI, but to complete our
# tasks, we need it. Wait here until it's up.
cookie_file = args.root_prefix + "/var/run/xapi_init_complete.cookie"
while not os.path.exists(cookie_file):
time.sleep(1)
- signal.signal(signal.SIGHUP, handler)
-
bridges = {} # Map from bridge name to nicira-bridge-id
iface_ids = {} # Map from xs-vif-uuid to iface-id
vm_ids = {} # Map from xs-vm-uuid to vm-id
seqno = idl.change_seqno # Sequence number when we last processed the db
while True:
+ unixctl_server.run()
+ if exiting:
+ break;
+
idl.run()
- if not force_run and seqno == idl.change_seqno:
+ if not flush_cache and seqno == idl.change_seqno:
poller = ovs.poller.Poller()
+ unixctl_server.wait(poller)
idl.wait(poller)
poller.block()
continue
- if force_run:
- vlog.info("Forced to re-run as the result of a SIGHUP")
+ if flush_cache:
+ vlog.info("Flushing cache as the result of unixctl.")
bridges = {}
iface_ids = {}
vm_ids = {}
- force_run = False
+ flush_cache = False
seqno = idl.change_seqno
txn = ovs.db.idl.Transaction(idl)
iface_ids = new_iface_ids
vm_ids = new_vm_ids
+ txn.add_comment("ovs-xapi-sync: Updating records from XAPI")
txn.commit_block()
+ unixctl_server.close()
+ idl.close()
+
if __name__ == '__main__':
try: