import sys
import os
-from subprocess import call
+from subprocess import call, Popen, PIPE
def losetup(source, offset=0):
- # XXX we avoid colliding with other instances of ourself,
- # but when it comes to other loop-device users we just
- # pick a range things don't seem to use and hope...
lockfilename = '/tmp/losetup.lock'
os.close(os.open(lockfilename, os.O_CREAT+os.O_EXCL)) #lock
try:
- loopdevice = None
- for i in xrange(32,60): # totally arbitrary, just looks to be unused on black-mesa
- filename = '/dev/loop%d'%i
- if 0 == len(file(filename).read(1)):
- loopdevice = filename # it's empty
- break
- if loopdevice is not None:
- call(['losetup', '-o', str(offset), loopdevice, source])
- else:
+ loopdevice = Popen(['losetup', '-f'], stdout=PIPE).communicate()[0].rstrip()
+ if loopdevice == '':
raise RuntimeError('out of loop devices for copying VM image: too many at once?')
+ if call(['losetup', '-o', str(offset), loopdevice, source]) != 0:
+ raise RuntimeError('losetup failed')
finally:
os.unlink(lockfilename) #unlock
return loopdevice