From 02f2da11ae21cfae5be6ebc2e05ff5bf6612b44d Mon Sep 17 00:00:00 2001 From: Mitchell E Berger Date: Tue, 8 Nov 2011 21:58:02 -0500 Subject: [PATCH] Add DB/LVM disk consistency checker and web/checkdisks remctl --- debian/changelog | 6 +++ debian/control | 4 +- host/usr/sbin/invirt-check-disks | 71 +++++++++++++++++++++++++++++++++++ host/usr/sbin/invirt-remote | 3 ++ server/usr/sbin/invirt-remote-proxy | 2 +- 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100755 host/usr/sbin/invirt-check-disks diff --git a/debian/changelog b/debian/changelog index 1ad3152..32bc4a7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +invirt-remote (0.4.12) unstable; urgency=low + + * Add DB/LVM disk consistency checker and web/checkdisks remctl + + -- Mitchell Berger Tue, 08 Nov 2011 21:52:00 -0500 + invirt-remote (0.4.11) unstable; urgency=low * Don't let the janitor try to cleanup nonexistent LVs diff --git a/debian/control b/debian/control index 69dceb9..4d8bd96 100644 --- a/debian/control +++ b/debian/control @@ -22,8 +22,8 @@ Description: Invirt remote-control server Package: invirt-remote-host Architecture: all Depends: ${misc:Depends}, daemon, remctl-server, invirt-console-host, - invirt-vnc-server, python-cjson, python-pyinotify, python-yaml, - util-linux, openbsd-inetd + invirt-vnc-server, python-cjson, python-pyinotify, python-sqlalchemy, + python-yaml, util-linux, openbsd-inetd Description: Installs the Invirt host remctl configuration This is the remctl configuration for an Invirt host. It allows any commands to be run from the Invirt remote server diff --git a/host/usr/sbin/invirt-check-disks b/host/usr/sbin/invirt-check-disks new file mode 100755 index 0000000..b118dfa --- /dev/null +++ b/host/usr/sbin/invirt-check-disks @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +from invirt import database as db +from invirt.config import structs as config +import sqlalchemy as sa +from subprocess import Popen, PIPE + +prefix = 'd_' + +# First figure out what the database thinks our sets of disks and sizes are +db.connect() +s = sa.sql.select([db.machine_table.c.name, db.disk_table.c.guest_device_name, + db.disk_table.c.size], + db.machine_table.c.machine_id == db.disk_table.c.machine_id, + [db.machine_table, db.disk_table]) +dbresult = db.session.execute(s) +db_disks = {} +for (machine, device, size) in dbresult.fetchall(): + db_disks['d_' + machine + '_' + device] = int(size) + +# Now figure out what the disk images actually in existence look like +p = Popen(['/sbin/lvs', '--noheadings', '-o', 'lv_name,lv_size', '--units', 'm', + '--unbuffered', '--nosuffix', '--separator', ':', config.lvm.vg], + stdout=PIPE) +lvresult = p.communicate()[0] +lv_disks = {} +for lv in lvresult.split(): + (lvname, size) = lv.split(':') + if not lvname.startswith(prefix): + continue + # We only want the whole number of MiB, to match the database + lv_disks[lvname] = int(float(size)) + +missing_disks = [] +orphaned_disks = [] +size_discrepancies = [] + +for disk in db_disks: + if disk not in lv_disks: + missing_disks.append(disk) + elif db_disks[disk] != lv_disks[disk]: + size_discrepancies.append(disk) +for disk in lv_disks: + if disk not in db_disks: + orphaned_disks.append(disk) + +if missing_disks: + print '===== The following disks are in the DB but the LVs do not exist' + missing_disks.sort() + for disk in missing_disks: + print disk.ljust(45) + 'DB: %s' % str(db_disks[disk]).rjust(6) + print '\n' +if orphaned_disks: + print '===== The following LVs exist but are not assigned to a VM' + orphaned_disks.sort() + for disk in orphaned_disks: + print disk.ljust(59) + 'LVM: %s' % str(lv_disks[disk]).rjust(6) + print '\n' +if size_discrepancies: + print '===== The following disks have different sizes in the DB and LVM' + size_discrepancies.sort() + for disk in size_discrepancies: + print disk.ljust(45) +\ + 'DB: %s LVM: %s' % (str(db_disks[disk]).rjust(6), + str(lv_disks[disk]).rjust(6)) + print '\n' +print 'There are %i inconsistencies between the DB and LVM at this time.' %\ + (missing_disks.__len__() + + orphaned_disks.__len__() + + size_discrepancies.__len__()) + diff --git a/host/usr/sbin/invirt-remote b/host/usr/sbin/invirt-remote index ceb8182..5168da8 100755 --- a/host/usr/sbin/invirt-remote +++ b/host/usr/sbin/invirt-remote @@ -26,6 +26,9 @@ case "$TYPE" in vnccert) COMMAND=/usr/bin/invirt-vnc-getcert ;; + checkdisks) + COMMAND=/usr/sbin/invirt-check-disks + ;; *) echo "ERROR: invalid subcommand" exit 34 diff --git a/server/usr/sbin/invirt-remote-proxy b/server/usr/sbin/invirt-remote-proxy index b70eb4d..ca7dcf8 100755 --- a/server/usr/sbin/invirt-remote-proxy +++ b/server/usr/sbin/invirt-remote-proxy @@ -18,7 +18,7 @@ case "$TYPE/$SERVICE" in invirt-remote-vnccert "$@" ;; web/availability | web/avail ) invirt-remote-availability "$@" ;; - web/lvcreate | web/lvremove | web/lvrename | web/lvresize | web/vgcapacity ) + web/lvcreate | web/lvremove | web/lvrename | web/lvresize | web/vgcapacity | web/checkdisks ) invirt-remote-lvm "$SERVICE" "$@" ;; control/help ) -- 1.7.9.5