[DeviceManager] Support format a VFAT filesystem larger than 2GB
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / DeviceManager / plugin.py
index ec85d0f..c83d161 100755 (executable)
@@ -102,41 +102,41 @@ class DeviceManagerConfiguration(Screen, ConfigListScreen):
 
 class DeviceManager(Screen):
        skin = """
-               <screen position="center,center" size="670,400" title="DeviceManager">
+               <screen position="center,center" size="590,350" title="DeviceManager">
                        <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
-                       <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
-                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
-                       <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="160,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="300,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="440,0" size="140,40" alphatest="on" />
                        <widget name="key_red" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
-                       <widget name="key_green" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
-                       <widget name="key_yellow" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
-                       <widget name="key_blue" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
-                       <ePixmap pixmap="skin_default/div-h.png" position="0,48" size="670,2" alphatest="on" />
-                       <widget source="menu" render="Listbox" position="0,48" size="670,350" scrollbarMode="showOnDemand">
+                       <widget name="key_green" position="160,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_yellow" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
+                       <widget name="key_blue" position="440,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
+                       <ePixmap pixmap="skin_default/div-h.png" position="0,48" size="590,2" alphatest="on" />
+                       <widget source="menu" render="Listbox" position="0,48" size="590,350" scrollbarMode="showOnDemand">
                                <convert type="TemplatedMultiContent">
                                {"templates":
                                        {"default": (54,[
-                                                       MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor  - model
-                                                       MultiContentEntryText(pos = (100, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
-                                                       MultiContentEntryText(pos = (230, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
-                                                       MultiContentEntryText(pos = (360, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
-                                                       MultiContentEntryText(pos = (490, 32), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
-                                                       MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # png 5 is the div pixmap
+                                                       MultiContentEntryText(pos = (50, 0), size = (510, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor  - model
+                                                       MultiContentEntryText(pos = (50, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
+                                                       MultiContentEntryText(pos = (170, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
+                                                       MultiContentEntryText(pos = (290, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
+                                                       MultiContentEntryText(pos = (410, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
+                                                       MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # png 5 is the div pixmap
                                                ]),
                                        "partitions": (98, [
-                                                       MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
-                                                       MultiContentEntryText(pos = (100, 32), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
-                                                       MultiContentEntryText(pos = (100, 54), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
-                                                       MultiContentEntryText(pos = (100, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
-                                                       MultiContentEntryText(pos = (230, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
-                                                       MultiContentEntryText(pos = (380, 76), size = (200, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
-                                                       MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (670, 2), png = 6), # png 6 is the div pixmap
+                                                       MultiContentEntryText(pos = (50, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
+                                                       MultiContentEntryText(pos = (50, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
+                                                       MultiContentEntryText(pos = (50, 54), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
+                                                       MultiContentEntryText(pos = (50, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
+                                                       MultiContentEntryText(pos = (180, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
+                                                       MultiContentEntryText(pos = (310, 76), size = (190, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
+                                                       MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (590, 2), png = 6), # png 6 is the div pixmap
                                                ]),
                                        "mountpoint": (54,[
                                                        MultiContentEntryPixmapAlphaTest(pos = (10, 7), size = (30, 30), png = 0), # index 0: picture
                                                        MultiContentEntryText(pos = (40, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 name
                                                        MultiContentEntryText(pos = (40, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 path
-                                                       MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # index 5 is the div pixmap
+                                                       MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # index 5 is the div pixmap
                                                ])
                                        },
                                        "fonts": [gFont("Regular", 22),gFont("Regular", 16),gFont("Regular", 28)],
@@ -270,7 +270,7 @@ class DeviceManager(Screen):
                if self.currDevice is None or self.currPartition is None:
                        return
                partition =  self.currPartition["partition"]
-               if not os.access("/autofs/%s"%partition,0):
+               if deviceinfo.isMountable(partition) is False:
                        self.session.open(MessageBox, _("This partition is not mountable.\nYou need to check or format this partition."), MessageBox.TYPE_ERROR, timeout = 10)
                        return
                self["key_red"].setText(_("Partitions"))
@@ -295,31 +295,40 @@ class DeviceManager(Screen):
                self["menu"].setList(self.mountPointList)
 
        def getCurrentDevice(self):
-               if self.currList == "default":
+               try:
                        return self["menu"].getCurrent()[6]
-               return None
+               except:
+                       return None
 
        def getCurrentPartition(self):
-               if self.currList == "partitions":
+               try:
                        return self["menu"].getCurrent()[7]
-               return None
+               except:
+                       return None
 
        def keyOk(self):
 #              print "keyOk"
                if self.currList == "default":
                        self.currDevice = self.getCurrentDevice()
-                       if len(self.currDevice["partitions"]) == 0:
-                               self.session.open(MessageBox, _("No partition list found on device.\nPlease click BLUE key and do Initialize to use this device."), MessageBox.TYPE_ERROR, timeout = 10)
+                       if self.currDevice is not None:
+                               if len(self.currDevice["partitions"]) == 0:
+                                       self.session.open(MessageBox, _("No partition list found on device.\nPlease click BLUE key and do Initialize to use this device."), MessageBox.TYPE_ERROR, timeout = 10)
+                               else:
+                                       self.showPartitionList()
                        else:
-                               self.showPartitionList()
+                               self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10)
                elif self.currList == "partitions":
-                       currMountPoint = self.getCurrentPartition()["mountpoint"]
-                       currUuid = self.getCurrentPartition()["uuid"]
-                       if currMountPoint == "":
-                               self.currPartition = self.getCurrentPartition()
-                               self.showMountPointSetup()
+                       currentPartition = self.getCurrentPartition()
+                       if currentPartition is not None:
+                               currMountPoint = currentPartition["mountpoint"]
+                               currUuid = currentPartition["uuid"]
+                               if currMountPoint == "":
+                                       self.currPartition = currentPartition
+                                       self.showMountPointSetup()
+                               else:
+                                       self.doUmount(currMountPoint, self.showPartitionList)
                        else:
-                               self.doUmount(currMountPoint, self.showPartitionList)
+                               self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
                elif self.currList == "mountpoint":
 # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng)
                        currEntry = self["menu"].getCurrent()[3]
@@ -352,16 +361,21 @@ class DeviceManager(Screen):
 
        def keyYellow(self):
                if self.currList == "partitions":
-                       partition = self.getCurrentPartition()
                        self.choiceBoxFstype()
 
        def keyBlue(self):
                if self.currList == "default":
                        device = self.getCurrentDevice()
-                       self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
+                       if device is not None:
+                               self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
+                       else:
+                               self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10)
                elif self.currList == "partitions":
                        partition = self.getCurrentPartition()
-                       self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
+                       if partition is not None:
+                               self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
+                       else:
+                               self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
 
        def keyMenu(self):
                self.session.open(DeviceManagerConfiguration)
@@ -388,7 +402,10 @@ class DeviceManager(Screen):
                        return
                else:
                        partition = self.getCurrentPartition()
-                       self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
+                       if partition is not None:
+                               self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
+                       else:
+                               self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
 
 # about mount funcs..
        def doUmount(self, mountpoint, callback):
@@ -508,7 +525,7 @@ class DeviceInit(Screen):
                self.devicesize = int(devicesize)
                self.inputbox_partitions = 1
                self.inputbox_partitionSizeList = []
-               self.inputbox_partitionSizeTotal = self.inputbox_partitionSizeRemain = int(self.devicesize/1024/1024)
+               self.inputbox_partitionSizeTotal = int(self.devicesize/1024/1024)
                self.msgWaiting = None
                self.msgWaitingMkfs = None
                self.devicenumber = 0
@@ -522,6 +539,16 @@ class DeviceInit(Screen):
                self.exitMessageTimer.callback.append(self.exitMessage)
                self.msg = ""
                self.fstype = None
+               self.mkfs_cmd = ""
+               self.doMkfsTimer = eTimer()
+               self.doMkfsTimer.callback.append(self.doMkfs)
+               self.doInitializeTimer = eTimer()
+               self.doInitializeTimer.callback.append(self.doInitialize)
+
+               self.partitionType = "MBR"
+               self.maxPartNum = 4
+               self.inputbox_partitionSizeRemain = self.inputbox_partitionSizeTotal
+               self.unit = "MB"
 
        def timerStart(self):
                self.initStartTimer.start(100,True)
@@ -557,13 +584,19 @@ class DeviceInit(Screen):
                return True
 
        def InitializeStart(self):
+               if self.devicesize >= ( 2.2 * 1000 * 1000 * 1000 * 1000 ): # 2.2TB
+                       self.partitionType = "GPT"
+                       self.maxPartNum = 20
+                       self.inputbox_partitionSizeRemain = 100
+                       self.unit = "%"
+
                self.InputPartitionSize_step1()
 
        def InputPartitionSize_step1(self):
-               self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
+               self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-%d)" % self.maxPartNum), text="1", maxSize=False, type=Input.NUMBER)
 
        def InputPartitionSize_step1_CB(self, ret):
-               if ret is not None and int(ret) in range(1,5): # ret in 1~4
+               if ret is not None and int(ret) in range(1,self.maxPartNum+1): # MBR 1~4, GPT 1~20
                        self.inputbox_partitions = int(ret)
                        self.InputPartitionSize_step2()
                else:
@@ -578,7 +611,7 @@ class DeviceInit(Screen):
                        self.choiceBoxFstype()
                else:
                        text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
-                       self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Max = %d MB)")%(current_partition,self.inputbox_partitionSizeRemain ), text=text, maxSize=False, type=Input.NUMBER)
+                       self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Unit = %s, Max = %d %s)")%(current_partition, self.unit, self.inputbox_partitionSizeRemain, self.unit), text=text, maxSize=False, type=Input.NUMBER)
 
        def InputPartitionSize_step2_CB(self, ret):
                if ret is not None:
@@ -613,8 +646,8 @@ class DeviceInit(Screen):
 #              print self.inputbox_partitionSizeList
                partitionsInfo = ""
                for index in range(len(self.inputbox_partitionSizeList)):
-                       print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
-                       partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
+                       print "partition %d : %s %s"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
+                       partitionsInfo += "partition %d : %s %s\n"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
                partitionsInfo += "filesystem type : %s"%(self.fstype)
                self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
 
@@ -632,10 +665,28 @@ class DeviceInit(Screen):
                        msg += _("\nDevice : %s")%self.device
                        msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
                        for index in range(len(self.inputbox_partitionSizeList)):
-                               msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
+                               msg += _("\npartition %d : %s %s")%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
                        self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
-                       set = ""
-                       partitions = len(self.inputbox_partitionSizeList)
+                       self.doInitializeTimer.start(500,True)
+
+       def doInitialize(self):
+               def CheckPartedVer():
+                       cmd = 'parted --version'
+                       lines = os.popen(cmd).readlines()
+                       for l in lines:
+                               if l.find("parted (GNU parted)") != -1:
+                                       ver = l.split()[3].strip()
+                                       break
+                       try:
+                               ver = float(ver)
+                       except:
+                               print "[CheckPartedVer] check parted version Failed!"
+                               return 0
+                       return ver
+
+               partitions = len(self.inputbox_partitionSizeList) # get num of partition
+               set = ""
+               if self.partitionType == "MBR":
                        if partitions == 1:
                                cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
                        else:
@@ -646,11 +697,47 @@ class DeviceInit(Screen):
                                                set +=";\n"
                                set+="y\n"
                                cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
-                       self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
+
+               elif self.partitionType == "GPT": # partition type is GPT
+                       setAlign = ""
+                       partedVer = CheckPartedVer()
+                       if partedVer >= 2.1: # align option is supported in version 2.1 or later
+                               setAlign = "--align optimal"
+
+                       if partitions == 1:
+                               cmd = 'parted %s /dev/%s --script mklabel gpt mkpart disk ext2 0%% 100%%' % (setAlign, self.device)
+                       else: # has multiple partitions
+                               p_current = 0
+                               for p in range(partitions):
+                                       if p == 0:
+                                               p_start = p_current
+                                               p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / 100 )
+                                               p_current = p_end
+                                       elif p > 0 and partitions > (p + 1):
+                                               p_start = p_current
+                                               p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / 100 )+ p_start
+                                               p_current = p_end
+                                       elif partitions == (p + 1):
+                                               p_start = p_current
+                                               p_end = 100
+                                       if p_start == p_end:
+                                               p_end +=1
+                                       if p_end > 100:
+                                               continue
+                                       set += 'mkpart disk%d ext2 %d%% %d%% ' % (p + 1, p_start, p_end)
+                               cmd = 'parted %s /dev/%s --script mklabel gpt %s' % (setAlign, self.device, set)
+               else:
+                       errorMsg = "Invalid partitioning type"
+                       self.msgWaiting.run_close(False, errorMsg)
+                       return
+               self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
 
        def initInitializeFinished(self, result, retval, extra_args = None):
                if retval == 0:
-                       cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
+                       if self.partitionType == "MBR":
+                               cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
+                       else: # is GPT
+                               cmd = "sleep 5"
                        self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
                else:
                        errorMsg = "initInitializing device Error at /dev/%s"%self.device
@@ -670,7 +757,12 @@ class DeviceInit(Screen):
                                if len(res[3]) > 3 and res[3][:2] == "sd":
                                        self.newpartitions += 1
                partitions.close()
-               self.msgWaiting.run_close(True)
+               partNum = len(self.inputbox_partitionSizeList) # get num of partition
+               if self.newpartitions != partNum:
+                       errorMsg = "Partitioning device Error at /dev/%s"%self.device
+                       self.msgWaiting.run_close(False, errorMsg)
+               else:
+                       self.msgWaiting.run_close(True)
 #              self.createFilesystem(self.newpartitions)
 
        def createFilesystem(self, newpartitions):
@@ -707,6 +799,9 @@ class DeviceInit(Screen):
                                cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
                        else:
                                cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
+                               if partitionsize > 2 * 1024 * 1024: # if partiton size larger then 2GB, use FAT32
+                                       cmd += " -F 32"
+
                else:
                        self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
                        return
@@ -714,9 +809,15 @@ class DeviceInit(Screen):
                msg = _("Create filesystem, please wait ...")
                msg += _("\nPartition : %s") % (fulldevicename)
                msg += _("\nFilesystem : %s") % (self.fstype)
-               msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
+               msg += _("\nDisk Size : %s MB") % (self.inputbox_partitionSizeTotal)
+               msg += _("\nPartition Size : %d %s\n") % (int(self.inputbox_partitionSizeList[self.devicenumber-1]), self.unit)
                self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
-               self.deviceInitConsole.ePopen(cmd, self.createFilesystemFinished, (self.device, fulldevicename))
+               self.mkfs_cmd = cmd
+               self.doMkfsTimer.start(500,True)
+
+       def doMkfs(self):
+               fulldevicename = "/dev/" + self.device + str(self.devicenumber)
+               self.deviceInitConsole.ePopen(self.mkfs_cmd, self.createFilesystemFinished, (self.device, fulldevicename))
 
        def createFilesystemFinished(self, result, retval, extra_args = None):
                device = extra_args[0]
@@ -777,6 +878,8 @@ class DeviceCheck(Screen):
                self.onLayoutFinish.append(self.timerStart)
                self.checkStartTimer = eTimer()
                self.checkStartTimer.callback.append(self.confirmMessage)
+               self.umountTimer = eTimer()
+               self.umountTimer.callback.append(self.doUnmount)
 
        def timerStart(self):
                self.checkStartTimer.start(100,True)
@@ -800,7 +903,6 @@ class DeviceCheck(Screen):
                print "deviceCheckStart "
                print "partition : ", self.partition
                device = self.partition["partition"]
-               mountpoint = self.partition["mountpoint"]
                fstype = self.partition["fstype"]
                fssize = self.partition["size"]
                if device is not None and fstype.startswith("ext"):
@@ -808,13 +910,19 @@ class DeviceCheck(Screen):
                        msg += _("\nDevice : /dev/%s")%(device)
                        msg += _("\nFilesystem : %s")%(fstype)
                        self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
-                       if mountpoint != "":
-                               self.doUmountFsck(device, mountpoint, fstype)
-                       else:
-                               self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
+                       self.umountTimer.start(500,True)
                else:
                        self.exit()
 
+       def doUnmount(self):
+               device = self.partition["partition"]
+               mountpoint = self.partition["mountpoint"]
+               fstype = self.partition["fstype"]
+               if mountpoint != "":
+                       self.doUmountFsck(device, mountpoint, fstype)
+               else:
+                       self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
+
        def doUmountFsck(self, device, mountpoint, fstype):
                cmd = "umount /dev/%s" % device
                self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
@@ -880,6 +988,8 @@ class DeviceFormat(Screen):
                self.formatStartTimer = eTimer()
                self.formatStartTimer.callback.append(self.DeviceFormatStart)
                self.setHotplugDisabled = False
+               self.umountTimer = eTimer()
+               self.umountTimer.callback.append(self.doUnmount)
 
        def timerStart(self):
                self.formatStartTimer.start(100,True)
@@ -891,15 +1001,17 @@ class DeviceFormat(Screen):
                print "Filesystem : ",self.newfstype
                device = self.partition["partition"]
                devicepath = "/dev/"+device
-               mountpoint = self.partition["mountpoint"]
                fssize = self.partition["size"]
                newfstype = self.newfstype
-
                msg = _("Format filesystem, please wait ...")
                msg += _("\nDevice : %s")%(devicepath)
                msg += _("\nFilesystem : %s")%(newfstype)
                msg += _("\nSize : %s")%(byteConversion(fssize))
-               self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
+               self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False, msgBoxID = None)
+               self.umountTimer.start(500,True)
+
+       def doUnmount(self):
+               mountpoint = self.partition["mountpoint"]
                if mountpoint != "":
                        self.doumountPartition()
                else:
@@ -951,8 +1063,12 @@ class DeviceFormat(Screen):
                                cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
                                self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
                else:
-                       errorMsg = _("Can not change the partition ID for %s")%device
-                       self.msgWaiting.run_close(False,errorMsg)
+                       if result and result.find("Use GNU Parted") > 0:
+                               print "[DeviceManager] /dev/%s use GNU Parted!" % device
+                               self.refreshPartitionFinished("NORESULT", 0)
+                       else:
+                               errorMsg = _("Can not change the partition ID for %s")%device
+                               self.msgWaiting.run_close(False,errorMsg)
 
        def refreshPartitionFinished(self, result, retval, extra_args = None):
                print "refreshPartitionFinished!"
@@ -982,6 +1098,8 @@ class DeviceFormat(Screen):
                                        cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
                                else:
                                        cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
+                                       if size > 2 * 1024: # if partiton size larger then 2GB, use FAT32
+                                               cmd += " -F 32"
                        self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
                else:
                        errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
@@ -1046,6 +1164,16 @@ class DeviceInfo():
                                blockDevice["vendor"] = vendor # str
                                self.blockDeviceList.append(blockDevice)
 
+       def SortPartList(self, partList):
+               length = len(partList)-1
+               sorted = False
+               while sorted is False:
+                       sorted = True
+                       for idx in range(length):
+                               if int(partList[idx][3:]) > int(partList[idx+1][3:]):
+                                       sorted = False
+                                       partList[idx] , partList[idx+1] = partList[idx+1], partList[idx]
+
        def getBlockDeviceInfo(self, blockdev):
                devpath = "/sys/block/" + blockdev
                error = False
@@ -1068,6 +1196,8 @@ class DeviceInfo():
                                if partition[:len(blockdev)] != blockdev:
                                        continue
                                partitions.append(partition)
+                       self.SortPartList(partitions)
+
                except IOError:
                        error = True
                return error, blacklisted, removable, partitions, size, model, vendor
@@ -1164,7 +1294,7 @@ class DeviceInfo():
 
        def isMounted(self, devpath, mountpoint):
                try:
-                       mounts = file('/proc/mounts').read().split('\n')
+                       mounts = file('/proc/mounts').readlines()
                        for x in mounts:
                                if not x.startswith('/'):
                                        continue
@@ -1175,15 +1305,48 @@ class DeviceInfo():
                        pass
                return False
 
+       def isMounted_anymp(self, devpath):
+               try:
+                       mounts = open('/proc/mounts', 'r').readlines()
+                       for x in mounts:
+                               if not x.startswith('/'):
+                                       continue
+                               _devPart, _mountpoint  = x.split()[:2]
+                               if devPart == _devPart:
+                                       return True
+               except:
+                       pass
+               return False
+
+       # check partition ID in extended or swap.
+       def checkSwapExtended(self, partition):
+               partID_Extended = ("5", "0f", "85", "c5", "d5")
+               partID_swap = ("82", "42")
+               data = os.popen("fdisk -l /dev/%s |grep %s" % (partition[:-1], partition )).readline().split()
+               if data[1] == '*':
+                       partID = str(data[5])
+               else:
+                       partID = str(data[4])
+#              print "partID: " ,partID
+#              print "checkIDS : ", partID_Extended + partID_swap
+               if partID in partID_Extended + partID_swap:
+                       return True
+               else:
+                       return False
+
        def isMountable(self, partition):
-               autofsPath = "/autofs/"+partition.device
-               mountable = False
+               if self.checkSwapExtended(partition):
+                       return False
+
                try:
-                       os.listdir(autofsPath)
-                       mountable = True
+                       if self.isMounted_anymp('/dev/'+partition):
+                               return True
+
+                       elif os.access('/autofs/'+partition, 0):
+                               return True
                except:
                        pass
-               return mountable
+               return False
 
        def isFstabAutoMounted(self, uuid, devpath, mountpoint):
 #              print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
@@ -1623,9 +1786,18 @@ def checkMounts(session):
                        for partition in listdir(devpath):
                                if not partition.startswith(blockdev):
                                        continue
+
+                               if deviceinfo.checkSwapExtended(partition):
+                                       continue
+
                                partitions.append(partition)
-                               if os.access('/autofs/'+partition,0) is False:
+
+                               if deviceinfo.isMounted_anymp('/dev/' + partition):
+                                       continue
+
+                               if os.access('/autofs/'+partition, 0) is False:
                                        noMountable_partitions.append(partition)
+
                        if len(partitions) == 0 or len(noMountable_partitions) != 0:
                                if noMountable_dev != "":
                                        noMountable_dev +=  ' '