From: <ga...@us...> - 2009-07-30 14:06:17
|
Revision: 5625 http://jnode.svn.sourceforge.net/jnode/?rev=5625&view=rev Author: galatnm Date: 2009-07-30 14:06:07 +0000 (Thu, 30 Jul 2009) Log Message: ----------- Refactor fdisk command. .- Better use of PartitionHelper class. .- Automatically create MBR and empty partition table if no MBR exists. Modified Paths: -------------- trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java trunk/fs/src/fs/org/jnode/partitions/command/PartitionHelper.java trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java Modified: trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java 2009-07-30 12:32:50 UTC (rev 5624) +++ trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java 2009-07-30 14:06:07 UTC (rev 5625) @@ -17,12 +17,11 @@ * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - + package org.jnode.partitions.command; import java.io.IOException; import java.io.PrintWriter; -import java.nio.ByteBuffer; import java.util.Collection; import java.util.List; @@ -37,7 +36,6 @@ import org.jnode.naming.InitialNaming; import org.jnode.partitions.ibm.IBMPartitionTable; import org.jnode.partitions.ibm.IBMPartitionTableEntry; -import org.jnode.partitions.ibm.IBMPartitionTableType; import org.jnode.partitions.ibm.IBMPartitionTypes; import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; @@ -53,183 +51,168 @@ * @author cr...@jn... */ public class FdiskCommand extends AbstractCommand { - // FIXME ... this is a dangerous command and it needs some extra checking to help - // avoid catastrophic errors. At the very least, it needs a mode that shows the - // user what would happen but does nothing. - private final FlagArgument FLAG_INIT_MBR = new FlagArgument( - "initMBR", Argument.OPTIONAL, "if set, init the device's Master Boot Record"); + // FIXME ... this is a dangerous command and it needs some extra checking to help + // avoid catastrophic errors. At the very least, it needs a mode that shows the + // user what would happen but does nothing. + private final FlagArgument FLAG_INIT_MBR = new FlagArgument( + "initMBR", Argument.OPTIONAL, "if set, init the device's Master Boot Record"); - private final FlagArgument FLAG_DELETE = new FlagArgument( - "delete", Argument.OPTIONAL, "if set, delete a partition"); + private final FlagArgument FLAG_DELETE = new FlagArgument( + "delete", Argument.OPTIONAL, "if set, delete a partition"); - private final FlagArgument FLAG_BOOTABLE = new FlagArgument( - "bootable", Argument.OPTIONAL, "if set, toggle the partition's bootable flag"); + private final FlagArgument FLAG_BOOTABLE = new FlagArgument( + "bootable", Argument.OPTIONAL, "if set, toggle the partition's bootable flag"); - private final FlagArgument FLAG_MODIFY = new FlagArgument( - "modify", Argument.OPTIONAL, "if set, modify or create a partition"); + private final FlagArgument FLAG_MODIFY = new FlagArgument( + "modify", Argument.OPTIONAL, "if set, modify or create a partition"); - private final IntegerArgument ARG_PARTITION = new IntegerArgument( - "partition", Argument.OPTIONAL, "Target partition number (0..3)"); + private final IntegerArgument ARG_PARTITION = new IntegerArgument( + "partition", Argument.OPTIONAL, "Target partition number (0..3)"); - private final LongArgument ARG_START = new LongArgument( - "start", Argument.OPTIONAL, "Partition start sector"); + private final LongArgument ARG_START = new LongArgument( + "start", Argument.OPTIONAL, "Partition start sector"); - private final LongArgument ARG_SECTORS = new LongArgument( - "sectors", Argument.OPTIONAL, "Partition size in sectors"); + private final LongArgument ARG_SECTORS = new LongArgument( + "sectors", Argument.OPTIONAL, "Partition size in sectors"); - private final SizeArgument ARG_BYTES = new SizeArgument( - "bytes", Argument.OPTIONAL, "Partition size in bytes (300K, 45M, etc)"); + private final SizeArgument ARG_BYTES = new SizeArgument( + "bytes", Argument.OPTIONAL, "Partition size in bytes (300K, 45M, etc)"); - private final IBMPartitionTypeArgument ARG_TYPE = new IBMPartitionTypeArgument( - "type", Argument.OPTIONAL, "IBM partition type code"); + private final IBMPartitionTypeArgument ARG_TYPE = new IBMPartitionTypeArgument( + "type", Argument.OPTIONAL, "IBM partition type code"); - private final DeviceArgument ARG_DEVICE = new DeviceArgument( - "deviceId", Argument.OPTIONAL, "Target device", BlockDeviceAPI.class); + private final DeviceArgument ARG_DEVICE = new DeviceArgument( + "deviceId", Argument.OPTIONAL, "Target device", BlockDeviceAPI.class); - public FdiskCommand() { - super("perform disk partition management tasks"); - registerArguments(FLAG_BOOTABLE, FLAG_DELETE, FLAG_INIT_MBR, FLAG_MODIFY, - ARG_DEVICE, ARG_PARTITION, ARG_START, ARG_SECTORS, ARG_BYTES, ARG_TYPE); - } + public FdiskCommand() { + super("perform disk partition management tasks"); + registerArguments(FLAG_BOOTABLE, FLAG_DELETE, FLAG_INIT_MBR, FLAG_MODIFY, + ARG_DEVICE, ARG_PARTITION, ARG_START, ARG_SECTORS, ARG_BYTES, ARG_TYPE); + } - public static void main(String[] args) throws Exception { - new FdiskCommand().execute(args); - } + public static void main(String[] args) throws Exception { + new FdiskCommand().execute(args); + } - public void execute() throws Exception { - final DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME); - PrintWriter out = getOutput().getPrintWriter(); - PrintWriter err = getError().getPrintWriter(); - if (!ARG_DEVICE.isSet()) { - // Show all devices. - listAvailableDevices(dm, out); - return; - } + public void execute() throws Exception { + final DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME); + PrintWriter out = getOutput().getPrintWriter(); + PrintWriter err = getError().getPrintWriter(); + if (!ARG_DEVICE.isSet()) { + // Show all devices. + listAvailableDevices(dm, out); + return; + } - Device dev = ARG_DEVICE.getValue(); - // FIXME PartitionHelper assumes that the device is an IDE device !?! - if (!(dev instanceof IDEDevice)) { - err.println(dev.getId() + " is not an IDE device"); - exit(1); - } - final PartitionHelper helper = new PartitionHelper(dev.getId(), out); + Device dev = ARG_DEVICE.getValue(); + // FIXME PartitionHelper assumes that the device is an IDE device !?! + if (!(dev instanceof IDEDevice)) { + err.println(dev.getId() + " is not an IDE device"); + exit(1); + } + final PartitionHelper helper = new PartitionHelper(dev.getId(), out); + try{ + helper.checkMBR(); + } catch (IOException ioex){ + out.println(ioex.getMessage()); + out.println("Create a new MBR with a valid partition table."); + helper.initMbr(); + helper.write(); + } - if (FLAG_BOOTABLE.isSet()) { - helper.toggleBootable(getPartitionNumber(helper)); - helper.write(); - } else if (FLAG_DELETE.isSet()) { - helper.deletePartition(getPartitionNumber(helper)); - helper.write(); - } else if (FLAG_MODIFY.isSet()) { - modifyPartition(helper, getPartitionNumber(helper), out); - helper.write(); - } else if (FLAG_INIT_MBR.isSet()) { - helper.initMbr(); - helper.write(); - } else { - printPartitionTable(dev, out); - } - } + if (FLAG_BOOTABLE.isSet()) { + helper.toggleBootable(getPartitionNumber(helper)); + helper.write(); + } else if (FLAG_DELETE.isSet()) { + helper.deletePartition(getPartitionNumber(helper)); + helper.write(); + } else if (FLAG_MODIFY.isSet()) { + modifyPartition(helper, getPartitionNumber(helper), out); + helper.write(); + } else if (FLAG_INIT_MBR.isSet()) { + helper.initMbr(); + helper.write(); + } else { + printPartitionTable(helper, out); + } + } - private int getPartitionNumber(PartitionHelper helper) { - int partNumber = ARG_PARTITION.getValue(); - if (partNumber >= helper.getNbPartitions() || partNumber < 0) { - throw new IllegalArgumentException("Partition number is invalid"); - } - return partNumber; - } + private int getPartitionNumber(PartitionHelper helper) { + int partNumber = ARG_PARTITION.getValue(); + if (partNumber >= helper.getNbPartitions() || partNumber < 0) { + throw new IllegalArgumentException("Partition number is invalid"); + } + return partNumber; + } - private void modifyPartition(PartitionHelper helper, int id, PrintWriter out) throws IOException { - long start = ARG_START.getValue(); - long size = ARG_SECTORS.isSet() ? ARG_SECTORS.getValue() : ARG_BYTES.getValue(); - IBMPartitionTypes type = ARG_TYPE.getValue(); + private void modifyPartition(PartitionHelper helper, int id, PrintWriter out) throws IOException { + long start = ARG_START.getValue(); + long size = ARG_SECTORS.isSet() ? ARG_SECTORS.getValue() : ARG_BYTES.getValue(); + IBMPartitionTypes type = ARG_TYPE.getValue(); - out.println("Init " + id + " with start = " + start - + ", size = " + size + ", fs = " - + Integer.toHexString(type.getCode())); - boolean sizeUnit = ARG_BYTES.isSet() ? - PartitionHelper.BYTES : PartitionHelper.SECTORS; - helper.modifyPartition(id, false, start, size, sizeUnit, type); - } + out.println("Init " + id + " with start = " + start + + ", size = " + size + ", fs = " + + Integer.toHexString(type.getCode())); + boolean sizeUnit = ARG_BYTES.isSet() ? + PartitionHelper.BYTES : PartitionHelper.SECTORS; + helper.modifyPartition(id, false, start, size, sizeUnit, type); + } - private void printPartitionTable(Device dev, PrintWriter out) - throws DeviceNotFoundException, ApiNotFoundException, IOException { - IDEDevice ideDev = null; - // FIXME ... this needs to be generalized to other disc device types. - if (dev instanceof IDEDevice) { - ideDev = (IDEDevice) dev; - } - BlockDeviceAPI api = dev.getAPI(BlockDeviceAPI.class); - IDEDriveDescriptor descriptor = ideDev.getDescriptor(); - int sectorSize = IDEConstants.SECTOR_SIZE; - ByteBuffer MBR = ByteBuffer.allocate(sectorSize); - api.read(0, MBR); - if (IBMPartitionTable.containsPartitionTable(MBR.array())) { - IBMPartitionTable partitionTable = - new IBMPartitionTable(new IBMPartitionTableType(), MBR.array(), dev); - if (ideDev != null) { - out.println("IDE Disk : " + dev.getId() + ": " + - descriptor.getSectorsIn28bitAddressing() * 512 + " bytes"); - } - out.println("Device Boot Start End Blocks System"); + private void printPartitionTable(PartitionHelper helper, PrintWriter out) + throws DeviceNotFoundException, ApiNotFoundException, IOException { + IDEDevice ideDev = helper.getDevice(); + IDEDriveDescriptor descriptor = ideDev.getDescriptor(); + int sectorSize = IDEConstants.SECTOR_SIZE; + if (ideDev != null) { + out.println("IDE Disk : " + ideDev.getId() + ": " + + descriptor.getSectorsIn28bitAddressing() * 512 + " bytes"); + } + out.println("Device Boot Start End Blocks System"); + IBMPartitionTable partitionTable = helper.getPartitionTable(); + int i = 0; + for(IBMPartitionTableEntry entry : partitionTable){ + IBMPartitionTypes si = entry.getSystemIndicator(); + if (!entry.isEmpty()) { + long sectors = entry.getNrSectors(); - int i = 0; - for (IBMPartitionTableEntry entry : partitionTable) { - IBMPartitionTypes si = entry.getSystemIndicator(); - if (si != IBMPartitionTypes.PARTTYPE_EMPTY) { - // Calculate number of blocks - long sectors = entry.getNrSectors(); - long blocks = sectors; - long odd = 0; + out.println("ID " + i + " " + + (entry.getBootIndicator() ? "Boot" : "No") + " " + + entry.getStartLba() + " " + + (entry.getStartLba() + sectors) + " " + + entry.getNbrBlocks(sectorSize) + (entry.isOdd()?"":"+") + " " + si); + } + if (entry.isExtended()) { + final List<IBMPartitionTableEntry> exPartitions = partitionTable.getExtendedPartitions(); + int j = 0; + for (IBMPartitionTableEntry exEntry : exPartitions) { + si = exEntry.getSystemIndicator(); + // FIXME ... this needs work + out.println("ID " + i + " " + + (exEntry.getBootIndicator() ? "Boot" : "No") + " " + + exEntry.getStartLba() + " " + + "-----" /* (exEntry.getStartLba() + entry.getNrSectors()) */ + " " + + "-----" /* exEntry.getNrSectors() */ + " " + si); + j++; + } + } + i++; + } + } - if (sectorSize < 1024) { - blocks /= (1024 / sectorSize); - odd = sectors % (1024 / sectorSize); - } else { - blocks *= (sectorSize / 1024); - } - - out.println("ID " + i + " " + - (entry.getBootIndicator() ? "Boot" : "No") + " " + - entry.getStartLba() + " " + - (entry.getStartLba() + sectors) + " " + - blocks + ((odd!=0)?"+":"") + " " + si); - } - if (entry.isExtended()) { - final List<IBMPartitionTableEntry> exPartitions = partitionTable.getExtendedPartitions(); - int j = 0; - for (IBMPartitionTableEntry exEntry : exPartitions) { - si = exEntry.getSystemIndicator(); - // FIXME ... this needs work - out.println("ID " + i + " " + - (exEntry.getBootIndicator() ? "Boot" : "No") + " " + - exEntry.getStartLba() + " " + - "-----" /* (exEntry.getStartLba() + entry.getNrSectors()) */ + " " + - "-----" /* exEntry.getNrSectors() */ + " " + si); - j++; - } - } - i++; - } - } else { - out.println(" No valid MBR found on this device. Use --initMBR to initialize it."); - } - } - - private void listAvailableDevices(DeviceManager dm, PrintWriter out) { - final Collection<Device> allDevices = dm.getDevicesByAPI(BlockDeviceAPI.class); - for (Device dev : allDevices) { - out.println("Found device : " + dev.getId() + "[" + dev.getClass() + "]"); - if (dev instanceof IDEDevice) { - IDEDevice ideDevice = (IDEDevice) dev; - IDEDriveDescriptor desc = ideDevice.getDescriptor(); - if (desc.isDisk()) { - out.println(" IDE Disk : " + ideDevice.getId() + - "(" + desc.getModel() + " " + - desc.getSectorsIn28bitAddressing() * IDEConstants.SECTOR_SIZE + ")"); - } - } - } - } + private void listAvailableDevices(DeviceManager dm, PrintWriter out) { + final Collection<Device> allDevices = dm.getDevicesByAPI(BlockDeviceAPI.class); + for (Device dev : allDevices) { + out.println("Found device : " + dev.getId() + "[" + dev.getClass() + "]"); + if (dev instanceof IDEDevice) { + IDEDevice ideDevice = (IDEDevice) dev; + IDEDriveDescriptor desc = ideDevice.getDescriptor(); + if (desc.isDisk()) { + out.println(" IDE Disk : " + ideDevice.getId() + + "(" + desc.getModel() + " " + + desc.getSectorsIn28bitAddressing() * IDEConstants.SECTOR_SIZE + ")"); + } + } + } + } } Modified: trunk/fs/src/fs/org/jnode/partitions/command/PartitionHelper.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/command/PartitionHelper.java 2009-07-30 12:32:50 UTC (rev 5624) +++ trunk/fs/src/fs/org/jnode/partitions/command/PartitionHelper.java 2009-07-30 14:06:07 UTC (rev 5625) @@ -35,7 +35,9 @@ import org.jnode.driver.bus.ide.IDEDevice; import org.jnode.fs.fat.BootSector; import org.jnode.fs.fat.GrubBootSector; +import org.jnode.partitions.ibm.IBMPartitionTable; import org.jnode.partitions.ibm.IBMPartitionTableEntry; +import org.jnode.partitions.ibm.IBMPartitionTableType; import org.jnode.partitions.ibm.IBMPartitionTypes; import org.jnode.partitions.ibm.MasterBootRecord; @@ -69,6 +71,10 @@ reloadMBR(); } + public IDEDevice getDevice(){ + return current; + } + public void initMbr() throws DeviceNotFoundException, ApiNotFoundException, IOException { out.println("Initialize MBR ..."); @@ -89,8 +95,6 @@ bs.getPartition(2).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY); bs.getPartition(3).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY); } - - // reloadMBR(); } public void write() throws IOException, Exception { @@ -117,11 +121,23 @@ bs = new BootSector(MBR.array()); } - private void checkMBR() throws IOException { + public void checkMBR() throws IOException { if (!MBR.containsPartitionTable()) - throw new IOException("This device doesn't contain a valid MBR, use --initmbr."); + throw new IOException("This device doesn't contain a valid partition table."); } + + public IBMPartitionTable getPartitionTable(){ + return new IBMPartitionTable(new IBMPartitionTableType(), MBR.array(), current); + } + public int getNbPartitions() { + return bs.getNbPartitions(); + } + + public IBMPartitionTableEntry getPartition(int partNr) { + return bs.getPartition(partNr); + } + public void modifyPartition(int id, boolean bootIndicator, long start, long size, boolean sizeUnit, IBMPartitionTypes fs) throws IOException { checkMBR(); @@ -141,9 +157,7 @@ entry.setNrSectors(nbSectors); } - public int getNbPartitions() { - return bs.getNbPartitions(); - } + public void deletePartition(int partNumber) throws IOException { checkMBR(); Modified: trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java 2009-07-30 12:32:50 UTC (rev 5624) +++ trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java 2009-07-30 14:06:07 UTC (rev 5625) @@ -32,6 +32,7 @@ private final byte[] bs; private final int ofs; + private long odd; @SuppressWarnings("unused") private final IBMPartitionTable parent; @@ -137,6 +138,23 @@ public void setNrSectors(long v) { LittleEndian.setInt32(bs, ofs + 12, (int) v); } + + public long getNbrBlocks(int sectorSize){ + long sectors = getNrSectors(); + long blocks = sectors; + if (sectorSize < 1024) { + blocks /= (1024 / sectorSize); + odd = getNrSectors() % (1024 / sectorSize); + } else { + blocks *= (sectorSize / 1024); + } + return blocks; + } + + public boolean isOdd(){ + return odd!=0; + } + public void clear() { for (int i = 0; i < 16; i++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |