Bug #18357: Fix tap-ctl parsing. Shutting down a domU with xen-4.1.2 doesn't terminate the corresponding blktap2 process, since one (other) VM uses a image file, which contains spaces in its file name. /var/log/xen/xend-debug.log has the following information: Unhandled exception in thread started by Traceback (most recent call last):   File "/usr/lib/python2.6/dist-packages/xen/xend/server/BlktapController.py", line 199, in finishDeviceCleanup     TapdiskController.destroy(path)   File "/usr/lib/python2.6/dist-packages/xen/xend/server/BlktapController.py", line 289, in destroy     tapdisk = TapdiskController.fromDevice(device)   File "/usr/lib/python2.6/dist-packages/xen/xend/server/BlktapController.py", line 278, in fromDevice     TapdiskController.list())   File "/usr/lib/python2.6/dist-packages/xen/xend/server/BlktapController.py", line 256, in list     key, value = pair.split('=') ValueError: need more than 1 value to unpack BlktapController calls "tap-ctl list", which outputs one line for each process. Each line contains key=value pairs without any quoting. # tap-ctl list | grep 'args=.*:.* ' pid=10145 minor=18 state=0 args=aio:/var/lib/libvirt/images/Xen Windows drivers (gplpv 308).iso (passing the output of tap-ctl through a pipe is important, since it switches to a different list-format when STDOUT is a tty.) BlktapController splits the output into lines using \n, then each line at each space, and finally each of these 'words' at the '=', which fails for the filename. Limit the number of splits as a fast work-around. --- a/tools/python/xen/xend/server/BlktapController.py +++ b/tools/python/xen/xend/server/BlktapController.py @@ -249,11 +249,12 @@ class TapdiskController(object): _list = TapdiskController.exc('list') if not _list: return [] - for line in _list.split('\n'): + for line in _list.splitlines(): tapdisk = TapdiskController.Tapdisk() - for pair in line.split(): - key, value = pair.split('=') + # Since 'tap-ctl list' does not escape blanks in the path, hard-code the current format using 4 pairs to prevent splitting the path + for pair in line.split(None, 3): + key, value = pair.split('=', 1) if key == 'pid': tapdisk.pid = value elif key == 'minor': @@ -264,7 +265,7 @@ class TapdiskController(object): elif key == 'state': tapdisk.state = value elif key == 'args' and value.find(':') != -1: - tapdisk.dtype, tapdisk.image = value.split(':') + tapdisk.dtype, tapdisk.image = value.split(':', 1) tapdisks.append(tapdisk)