Nathan McBride wrote:
> Yup, I got some help in IRC.  What I ended up doing was using regex to
> pull out each "/dev/loopX".  Then
> took the X and fed it to max which in turn gave me the highest numbered
> loop device in use.  After which I
> then just added 1 to X and added it to the end of "/dev/loop_".  The
> only other thing I had to do was put a
> check in incase there were no used loop devices in which case then it
> defaults to "/dev/loop0".

One might also consider reimplementing 'losetup -f' in python, but after
my own attempt I realize it might not be that practical, and is
potentially dangerous I suppose -- if, like me, you don't fully
understand the underlying system calls. I've attached my attempt for the
sake of discussion only, and not as a solution -- perhaps someone with
interest will correct any errors and make it usable. I would definitely
appreciate it.

Drifting off topic now... I copied most of the find_unused_loop_device
implementation in util-linux/lomount.c[1]. The main points of interest,
and potential doom due to my ignorance, are related to the fcntl.ioctl call:

1) the LOOP_GET_STATUS ioctl op const, isn't exposed in any of the
typical python modules that I can find, and as such I'm worried that
it's value is somehow platform dependent.

2) for a similar reason, I am passing a string of the largest allowed
length as the 3rd arg to the fcntl.ioctl call on line 33, since the size
of the returned data seems to be governed by a struct defined in loop.h,
which needs dev_t from a kernel header. Whew. This seems to work fine on
my ubuntu system, if sloppy. But, since I don't know, I tend to assume
it could cause problems with stability or security.

Anyway, thanks for the interesting question Nathan. Now I have some
reading to do. :)

Marty

[1]
http://www.google.com/codesearch?hl=en&q=show:3q3vE6vLdaY:0lRVP2J7BtU:j-QqODsRp3s&sa=N&ct=rd&cs_p=ftp://ftp.kernel.org/pub/linux/utils/util-linux/testing/util-linux-2.13-pre7.tar.gz&cs_f=util-linux-2.13-pre7/mount/lomount.c&start=1
#!/usr/bin/env python2.5
import os
import stat
import errno
import fcntl

if os.uname()[4] == 'x86_64':
    LOOP_GET_STATUS = 0x4C05
else:
    LOOP_GET_STATUS = 0x4C03

def find_unused_loop_device():
    """
    Return the next unused loop device node, returns None if the 
    next device cannot be determined (and swallows exceptions 
    encountered along the way: permission denied, no such file, etc). 
    """
    for loop_format in ['/dev/loop%d', '/dev/loop/%d']:
        for i in range(256):
            dev = loop_format % i
            try:
                st = os.stat(dev)
            except OSError:
                break # assume invalid loop_format
            
            if stat.S_ISBLK(st.st_mode):
                try:
                    fd = os.open(dev, os.O_RDONLY)
                except OSError:
                    pass # assume permission denied
                else:
                    try:
                        fcntl.ioctl(fd, LOOP_GET_STATUS, 1024*'\x00')
                    except IOError, e:
                        if e.errno == errno.ENXIO:
                            os.close(fd)
                            return dev
                    os.close(fd)

if __name__ == '__main__':
    print find_unused_loop_device()
                    
                


    
    
_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to