dom0/qvm-block: handle block-attach errors (#515)
This commit is contained in:
parent
5ae9f98c8c
commit
1a07bc241d
@ -294,7 +294,7 @@ def block_check_attached(backend_vm, device, backend_xid = None):
|
|||||||
xs.transaction_end(xs_trans)
|
xs.transaction_end(xs_trans)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def block_attach(vm, backend_vm, device, frontend=None, mode="w", auto_detach=False):
|
def block_attach(vm, backend_vm, device, frontend=None, mode="w", auto_detach=False, wait=True):
|
||||||
if not vm.is_running():
|
if not vm.is_running():
|
||||||
raise QubesException("VM %s not running" % vm.name)
|
raise QubesException("VM %s not running" % vm.name)
|
||||||
|
|
||||||
@ -325,6 +325,36 @@ def block_attach(vm, backend_vm, device, frontend=None, mode="w", auto_detach=Fa
|
|||||||
|
|
||||||
xl_cmd = [ '/usr/sbin/xl', 'block-attach', vm.name, backend_dev, frontend, mode, str(backend_vm.xid) ]
|
xl_cmd = [ '/usr/sbin/xl', 'block-attach', vm.name, backend_dev, frontend, mode, str(backend_vm.xid) ]
|
||||||
subprocess.check_call(xl_cmd)
|
subprocess.check_call(xl_cmd)
|
||||||
|
if wait:
|
||||||
|
be_path = '/local/domain/%d/backend/vbd/%d/%d' % (backend_vm.xid, vm.xid, block_name_to_devid(frontend))
|
||||||
|
# There is no way to use xenstore watch with a timeout, so must check in a loop
|
||||||
|
interval = 0.100
|
||||||
|
# 5sec timeout
|
||||||
|
timeout = 5/interval
|
||||||
|
while timeout > 0:
|
||||||
|
be_state = xs.read('', be_path + '/state')
|
||||||
|
hotplug_state = xs.read('', be_path + '/hotplug-status')
|
||||||
|
if be_state is None:
|
||||||
|
raise QubesException("Backend device disappeared, something weird happend")
|
||||||
|
elif int(be_state) == 4:
|
||||||
|
# Ok
|
||||||
|
return
|
||||||
|
elif int(be_state) > 4:
|
||||||
|
# Error
|
||||||
|
error = xs.read('/local/domain/%d/error/backend/vbd/%d/%d/error' % (backend_vm.xid, vm.xid, block_name_to_devid(frontend)))
|
||||||
|
if error is None:
|
||||||
|
raise QubesException("Error while connecting block device: " + error)
|
||||||
|
else:
|
||||||
|
raise QubesException("Unknown error while connecting block device")
|
||||||
|
elif hotplug_state == 'error':
|
||||||
|
hotplug_error = xs.read('', be_path + '/hotplug-error')
|
||||||
|
if hotplug_error:
|
||||||
|
raise QubesException("Error while connecting block device: " + hotplug_error)
|
||||||
|
else:
|
||||||
|
raise QubesException("Unknown hotplug error while connecting block device")
|
||||||
|
time.sleep(interval)
|
||||||
|
timeout -= interval
|
||||||
|
raise QubesException("Timeout while waiting for block defice connection")
|
||||||
|
|
||||||
def block_detach(vm, frontend = "xvdi", vm_xid = None):
|
def block_detach(vm, frontend = "xvdi", vm_xid = None):
|
||||||
# Get XID if not provided already
|
# Get XID if not provided already
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
from qubes.qubes import QubesVmCollection
|
from qubes.qubes import QubesVmCollection, QubesException
|
||||||
from qubes.qubesutils import block_list,block_attach,block_detach,block_check_attached
|
from qubes.qubesutils import block_list,block_attach,block_detach,block_check_attached
|
||||||
from qubes.qubesutils import kbytes_to_kmg, bytes_to_kmg
|
from qubes.qubesutils import kbytes_to_kmg, bytes_to_kmg
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
@ -94,7 +94,11 @@ def main():
|
|||||||
else:
|
else:
|
||||||
kwargs['mode'] = dev['mode']
|
kwargs['mode'] = dev['mode']
|
||||||
kwargs['auto_detach'] = options.auto_detach
|
kwargs['auto_detach'] = options.auto_detach
|
||||||
block_attach(vm, backend_vm, dev['device'], **kwargs)
|
try:
|
||||||
|
block_attach(vm, backend_vm, dev['device'], **kwargs)
|
||||||
|
except QubesException as e:
|
||||||
|
print >> sys.stderr, "ERROR: %s" % str(e)
|
||||||
|
sys.exit(1)
|
||||||
elif options.do_detach:
|
elif options.do_detach:
|
||||||
if (len (args) < 1):
|
if (len (args) < 1):
|
||||||
parser.error ("You must provide device or vm name!")
|
parser.error ("You must provide device or vm name!")
|
||||||
|
Loading…
Reference in New Issue
Block a user