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)
|
||||
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():
|
||||
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) ]
|
||||
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):
|
||||
# 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 kbytes_to_kmg, bytes_to_kmg
|
||||
from optparse import OptionParser
|
||||
@ -94,7 +94,11 @@ def main():
|
||||
else:
|
||||
kwargs['mode'] = dev['mode']
|
||||
kwargs['auto_detach'] = options.auto_detach
|
||||
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:
|
||||
if (len (args) < 1):
|
||||
parser.error ("You must provide device or vm name!")
|
||||
|
Loading…
Reference in New Issue
Block a user