From 7ae0c52e6da7a24a6dfe51904523130990d9aaa1 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sat, 1 Oct 2011 02:52:56 +0200 Subject: [PATCH] dom0: introduce ClockVM - timesource for dom0 (#361) --- dom0/qvm-core/qubes.py | 35 +++++++++++++++++++++-- dom0/qvm-tools/qvm-get-clockvm | 39 +++++++++++++++++++++++++ dom0/qvm-tools/qvm-set-clockvm | 46 ++++++++++++++++++++++++++++++ dom0/qvm-tools/qvm-sync-dom0-clock | 14 ++++----- 4 files changed, 124 insertions(+), 10 deletions(-) create mode 100755 dom0/qvm-tools/qvm-get-clockvm create mode 100755 dom0/qvm-tools/qvm-set-clockvm diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index d92d9b6d..4aee678f 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1802,6 +1802,7 @@ class QubesVmCollection(dict): self.default_kernel = None self.updatevm_qid = None self.qubes_store_filename = store_filename + self.clockvm_qid = None def values(self): for qid in self.keys(): @@ -1988,6 +1989,15 @@ class QubesVmCollection(dict): else: return self[self.updatevm_qid] + def set_clockvm_vm(self, vm): + self.clockvm_qid = vm.qid + + def get_clockvm_vm(self): + if self.clockvm_qid is None: + return None + else: + return self[self.clockvm_qid] + def get_vm_by_name(self, name): for vm in self.values(): if (vm.name == name): @@ -2096,6 +2106,9 @@ class QubesVmCollection(dict): updatevm=str(self.updatevm_qid) \ if self.updatevm_qid is not None else "None", + clockvm=str(self.clockvm_qid) \ + if self.clockvm_qid is not None else "None", + default_kernel=str(self.default_kernel) \ if self.default_kernel is not None else "None", ) @@ -2255,6 +2268,11 @@ class QubesVmCollection(dict): if updatevm != "None" else None #assert self.default_netvm_qid is not None + clockvm = element.get("clockvm") + if clockvm is not None: + self.clockvm_qid = int(clockvm) \ + if clockvm != "None" else None + self.default_kernel = element.get("default_kernel") # Then, read in the TemplateVMs, because a reference to template VM @@ -2385,11 +2403,22 @@ class QubesVmCollection(dict): os.path.basename(sys.argv[0]), err)) return False + # if there was no clockvm entry in qubes.xml, try to determine default: + # root of default NetVM chain + if clockvm is None: + if self.default_netvm_qid is not None: + clockvm = self[self.default_netvm_qid] + # Find root of netvm chain + while clockvm.netvm_vm is not None: + clockvm = clockvm.netvm_vm + + self.clockvm_qid = clockvm.qid + + # Enable ntpd in ClockVM + if self.clockvm_qid is not None: + self[self.clockvm_qid].services['ntpd'] = True return True - - - class QubesDaemonPidfile(object): def __init__(self, name): self.name = name diff --git a/dom0/qvm-tools/qvm-get-clockvm b/dom0/qvm-tools/qvm-get-clockvm new file mode 100755 index 00000000..c6e151b6 --- /dev/null +++ b/dom0/qvm-tools/qvm-get-clockvm @@ -0,0 +1,39 @@ +#!/usr/bin/python2.6 +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +from qubes.qubes import QubesVmCollection +from optparse import OptionParser; + +def main(): + qvm_collection = QubesVmCollection() + qvm_collection.lock_db_for_reading() + qvm_collection.load() + qvm_collection.unlock_db() + clockvm = qvm_collection.get_clockvm_vm() + if clockvm is None: + print "" + else: + print clockvm.name + + + +main() diff --git a/dom0/qvm-tools/qvm-set-clockvm b/dom0/qvm-tools/qvm-set-clockvm new file mode 100755 index 00000000..84db6389 --- /dev/null +++ b/dom0/qvm-tools/qvm-set-clockvm @@ -0,0 +1,46 @@ +#!/usr/bin/python2.6 +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +from qubes.qubes import QubesVmCollection +from optparse import OptionParser; + +def main(): + usage = "usage: %prog " + parser = OptionParser (usage) + (options, args) = parser.parse_args () + if (len (args) != 1): + parser.error ("Missing argument!") + vmname = args[0] + + qvm_collection = QubesVmCollection() + qvm_collection.lock_db_for_writing() + qvm_collection.load() + vm = qvm_collection.get_vm_by_name(vmname) + if vm is None or vm.qid not in qvm_collection: + print "A VM with the name '{0}' does not exist in the system.".format(vmname) + exit(1) + + qvm_collection.set_clockvm_vm(vm) + qvm_collection.save() + qvm_collection.unlock_db() + +main() diff --git a/dom0/qvm-tools/qvm-sync-dom0-clock b/dom0/qvm-tools/qvm-sync-dom0-clock index ab588c05..f8cbf682 100755 --- a/dom0/qvm-tools/qvm-sync-dom0-clock +++ b/dom0/qvm-tools/qvm-sync-dom0-clock @@ -1,16 +1,16 @@ #!/bin/sh -UPDATES_VM=`qvm-get-updatevm` +CLOCK_VM=`qvm-get-clockvm` QREXEC_CLIENT=/usr/lib/qubes/qrexec_client -if [ -z "$UPDATES_VM" ]; then - echo "UpdateVM not set, exiting!" >&2 +if [ -z "$CLOCK_VM" ]; then + echo "ClockVM not set, exiting!" >&2 exit 1 fi -if ! xl domid "$UPDATES_VM" > /dev/null 2>&1; then - echo "UpdateVM not started, exiting!" +if ! xl domid "$CLOCK_VM" > /dev/null 2>&1; then + echo "ClockVM not started, exiting!" exit 1 fi @@ -19,7 +19,7 @@ fi # there seems to be no way to pass output of date +%s.%N to date, # so we use human-readable format -CURRENT_TIME="$($QREXEC_CLIENT -d $UPDATES_VM 'user:date -u' | +CURRENT_TIME="$($QREXEC_CLIENT -d $CLOCK_VM 'user:date -u' | dd count=1 2>/dev/null | grep '^[A-Za-z]* [A-Za-z]* [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [A-Z]* [0-9][0-9][0-9][0-9]$'| head -1)" @@ -29,6 +29,6 @@ if [ -n "$CURRENT_TIME" ] ; then sudo date -u -s "$CURRENT_TIME" ; echo Done. else - echo "Error while parsing the time obtained from the UpdateVM ($UPDATES_VM).." + echo "Error while parsing the time obtained from the ClockVM ($CLOCK_VM).." fi