sipb-xen-losetup: a half-sane way to use losetup
authorGreg Price <price@mit.edu>
Tue, 22 Apr 2008 20:15:57 +0000 (16:15 -0400)
committerGreg Price <price@mit.edu>
Tue, 22 Apr 2008 20:15:57 +0000 (16:15 -0400)
You should use this instead of plain losetup; everything that uses this
will at least not have races with other things using this.

If it's missing a feature (e.g. a losetup argument) you want,
it shouldn't be hard to add.

svn path=/trunk/packages/sipb-xen-dom0/; revision=449

files/usr/sbin/sipb-xen-losetup [new file with mode: 0755]

diff --git a/files/usr/sbin/sipb-xen-losetup b/files/usr/sbin/sipb-xen-losetup
new file mode 100755 (executable)
index 0000000..5776248
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env python2.5
+
+import sys
+import os
+from subprocess import call
+
+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:
+      raise RuntimeError('out of loop devices for copying VM image: too many at once?')
+  finally:
+    os.unlink(lockfilename) #unlock
+  return loopdevice
+
+def main(*argv):
+  args = argv[1:]
+  os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
+  if not (1 <= len(args) <= 2):
+    print >>sys.stderr, 'usage: %s sourcedevice [offset]' % argv[0]
+    print >>sys.stderr, 'prints resulting loopback device; don\'t forget to losetup -d'
+    return 2
+  print losetup(*args)
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main(*sys.argv))