#!/usr/bin/python
#                             -*- Mode: Python -*- 
# isi_tape_rescan
# 
# Author          : Ravi Iyer
# Created On      : Thu Mar 26 14:15:08 PDT 2009
# Last Modified By: Jeff Miller
# Last Modified On: Sat May  9 14:22:27 2009
# 
# Copyright (c) 2008, 2009
# Isilon System, Inc. All rights reserved.
# 

# Called by devd when tape or media changers come and go. Does a tape rescan
# to update the devices.xml file.


# import statements are last minute since typically this will be called
# for each device added or removed but only the first call will actually do
# a device rescan.  Just loading the tape and fc modules has a considerable
# overhead.
import isi.misc as misc


lock_file = "/tmp/isi_tape_rescan.lock"
obj_file = "/tmp/isi_tape_rescan.obj"

class RescanManager:
    def __init__(self, lock_file, obj_file):
        self.lock_file = lock_file
        self.obj_file = obj_file
        
    def rescan(self):
        try:
            if not  misc.ifs_mounted():
                return

            import os
            import cPickle
            
            # Update the data_file to indicate additional rescans are required.
            f = open(self.obj_file, 'wb')
            s = 'more'
            cPickle.dump(s,f)
            f.close()

            retry = False

            while os.path.exists(self.obj_file) or retry == True:
                try:  
                    # Lock the file and continue to rescan
                    lockfd = os.open(lock_file, \
                        os.O_RDWR|os.O_CREAT|os.O_EXLOCK|os.O_NONBLOCK, 0400)
                    # If successful,  While the data_file says to rescan,
                    # run rescan
                except OSError, err:  
                    return                    

                if os.path.exists(self.obj_file):
                    os.remove(self.obj_file)

                import isi.backup.tape as tape
                import isi.backup.fc as fc

                try:
                    tape.Proxy().rescan(cam_rescan = False)
                except:
                    import time
                    print "Rescan error, retrying"
                    time.sleep(2)
                    retry = True
                    
                retry = False
                os.close(lockfd)
                
            print "All done with rescanning %d " % os.getpid()
            
        except IOError, err:
            print "Error %d " % os.getpid()
RescanManager(lock_file, obj_file).rescan()
