home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
include
/
partitioning
/
auto_part_functions.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
14KB
|
457 lines
/**
* Module: auto_part_functions.ycp
*
* Authors: Andreas Schwab (schwab@suse.de)
* Klaus KΣmpf (kkaempf@suse.de)
*
* Purpose: This module define functions of general use
* to the automatic partitioner
*
* $Id: auto_part_functions.ycp 26727 2005-12-22 18:10:40Z fehr $
*
* needs global variables:
*
* integer bytes_per_unit
* integer first_logical_nr
* integer max_partitions
*
* defined functions:
global define size_of_region (list region) ``{
global define size_to_units (integer bytes) ``{
global define start_of_region (list region) ``{
global define end_of_region (list region) ``{
global define num_primary (list partitions) ``{
global define contiguous_selection (list selection) ``{
global define contains_extended (list partitions) ``{
global define extended_region (list partitions) ``{
global define calculate_selected_region (list selection, any extended_region) ``{
global define can_create_logical (list partitions) ``{
global define bootable (list region) ``{
global define can_resize( list partitions ) ``{
global define renumber_logical_partitions (list partitions) ``{
global define unused_extended_region (list partitions) ``{
global define unused_logical_region (list partitions) ``{
global define compute_max_partitions (map target) ``{
global define compute_max_primary (map target)
*
*/
{
import "Arch";
import "Partitions";
textdomain "storage";
include "partitioning/partition_defines.ycp";
// --------------------------------------------------------------
// helper functions
// Return the size of a disk region in bytes
define integer size_of_region (list<integer> region,
integer bytes_per_unit) ``{
return region[1]:0 * bytes_per_unit;
};
// Return the number of units that holds at least BYTES
define integer size_to_units( integer bytes,
integer bytes_per_unit) ``{
return (bytes + bytes_per_unit - 1) / bytes_per_unit;
};
// Return the start of the region.
define integer start_of_region (list<integer> region) ``{
return region[0]:0;
};
// Return the end of the region, ie. start of the next region
define integer end_of_region (list<integer> region) ``{
return region[0]:0 + region[1]:0;
};
// Return the number of primary partitions
define integer num_primary (list<map> partitions) ``{
integer n = 0;
foreach (map pentry, partitions, ``{
if (pentry["type"]:`unknown == `primary)
n = n + 1;
});
return n;
};
// The maximum partition number the kernel can handle for the target
// disk, count from 0 on, return the maximal allowed value for
// a partition number
define integer compute_max_partitions (map disk)
``{
integer ret = disk["max_primary"]:4 - 1;
if( disk["label"]:""=="msdos" )
{
if( disk["bus"]:"" == "IDE" )
{
ret = 63;
}
else
{
ret = 15;
}
}
return( ret );
};
// return the maximal number of primary partitions
define integer compute_max_primary (map disk) ``{
return disk["max_primary"]:4;
};
// Return whether the list of selected partitions is contiguous.
define boolean contiguous_selection (list<map> selection) ``{
boolean ret = true;
list<integer> last_region = nil;
foreach (map pentry, selection, ``{
if (!pentry["create"]:false) {
list<integer> region = pentry["region"]:[];
symbol type = pentry["type"]:`unknown;
if( last_region != nil &&
(end_of_region(last_region) < start_of_region(region)))
{
ret = false;
}
last_region = region;
}
});
return ret;
}; // contiguous_selection
// Return true if an extended partition exists
define boolean contains_extended (list<map> partitions) ``{
boolean ret = find( map p, partitions,
``(p["type"]:`unknown==`extended &&
!p["delete"]:false)) != nil;
return( ret );
};
define boolean ignored_partition( map disk, map part )
``{
// skip #3 on AlphaBSD and SparcBSD
boolean ret = disk["label"]:""=="bsd" || disk["label"]:""=="sun";
if( ret )
{
ret = part["nr"]:0 == 3;
}
return( ret );
};
// Return the region of the extended partition
define list<integer> extended_region (list<map> partitions) ``{
list<integer> ret = [ 0, 0 ];
foreach (map pentry, partitions, ``{
if (pentry["type"]:`unknown == `extended)
ret = (list<integer>) (pentry["region"]:[]);
});
return ret;
};
// Return the region for the selected partitions. If EXTENDED_REGION
// is not nil it is used to clip the region so that it is contained
// entirely within it.
define list<integer> calculate_selected_region( list selection,
list<integer> ext_region )
``{
integer start = -1;
integer end = 0;
if( size(selection) > 0)
{
start = start_of_region( selection[0,"region"]:[] );
end = end_of_region( selection[size(selection)-1,"region"]:[] );
}
if (start != -1)
{
if (size (ext_region)>0)
{
// Use only the part that is contained in the extended
// partition
if (start >= end_of_region (ext_region))
return [ 0, 0 ];
if (start < start_of_region (ext_region))
start = start_of_region (ext_region);
if (end > end_of_region (ext_region))
end = end_of_region (ext_region);
}
return [ start, end - start ];
}
return [ 0, 0 ];
}; // selected_region
// Check whether three logical partitions can be created without
// running past the kernel limit for the number of partitions
define boolean can_create_logical( list<map> partitions )
``{
list logicals = filter( map pentry, partitions,
``(pentry["type"]:`unknown == `logical));
integer num_logical = size (logicals);
return ((first_logical_nr + num_logical + 3) <= (max_partitions + 1));
};
// Check whether the boot partition is located entrely below the bootable
// cylinder limit
define boolean bootable(list<integer> region, integer bps)
``{
return( start_of_region(region) + size_to_units(size_of_boot,bps) <
Partitions::BootCyl() );
};
// Check if the given partition is a FAT partition
// Input: partition map to be checked (from targets)
// Return: true if partition is FAT, false otherwise
//
define boolean is_fat_partition( map partition ) ``{
return ( partition["fsid"]:-1 == 0x06 || // FAT16
partition["fsid"]:-1 == 0x0b || // Win95 FAT32 CHS
partition["fsid"]:-1 == 0x0c || // Win95 FAT32 LBA
partition["fsid"]:-1 == 0x0e ); // Win95 FAT16 LBA
}
// Check if the given partition is a NTFS partition
// Input: partition map to be checked (from targets)
// Return: true if partition is NTFS, false otherwise
//
define boolean is_ntfs_partition( map partition ) ``{
return ( partition["fsid"]:-1 == 0x07 || // HPFS/NTFS
partition["fsid"]:-1 == 0x86 || // NTFS-DatentrΣger
partition["fsid"]:-1 == 0x87 ); // NTFS-DatentrΣger
}
// Get the partition map with the highest minor number out of the given partition list
// Input: List of partition maps.
// Return: Partition map if found or $[] if not.
//
define map get_last_used_partition( list<map> partitions )
``{
map last_partition = $[];
integer minor = -1;
y2milestone( "get_last_used_partition p:%1", partitions );
foreach( map partition, partitions,
``{
if ( partition["nr"]:-1 > minor )
{
minor = partition["nr"]:-1;
last_partition = partition;
}
});
y2milestone( "get_last_used_partition ret %1", last_partition );
return last_partition;
}
// Check whether the partition list has a resizable partition as the highest partition.
// Input: List of partition maps
// Return: resizeable partition map or $[] if none found
//
define map can_resize( list<map> partitions )
``{
map last_used_partition = $[];
if( !Arch::i386 () )
{
y2warning( "Wrong architecture - can't resize partitions" );
return $[]; // for now
}
// Filter out empty space that might exist behind valid partitions.
// This space would be there as a pseudo partition of type `free.
//
list<map> partitions_local =
filter( map pentry, partitions, ``( pentry["type"]:`dummy != `free ));
last_used_partition = get_last_used_partition( partitions_local );
if ( last_used_partition == $[] ) return $[]; // no last resizeable partition found
// Check for supported filesystem types.
//
if( is_fat_partition( last_used_partition ) )
return last_used_partition;
else
return $[];
}
// Check if the given file does exist.
// Input: File to be checked incl. path as string, e.g. "/usr/lib/YaST2/clients/installation.ycp"
// This may also point to a directory.
// Return: true if found, false if not.
//
define boolean file_exist( string file_path ) ``{
boolean file_found = (integer)SCR::Read(.target.size, file_path) >= 0;
y2milestone( "file %1 found %2 ret:%3", file_path, file_found,
SCR::Read(.target.size, file_path) );
return file_found;
}
// Check whether the partition list has a resizable partition as the highest
// partition.
// Input: map of data containing the disk
// Return: true if there is NT on the system, otherwise false
//
define integer check_win_nt_system( map disk )
``{
boolean is_nt = false;
boolean go_on = true;
integer local_ret = 0;
boolean local_err = false;
list<map> partitions = [];
list<map> partitions_local = [];
string fat_partition = "";
partitions = disk["partitions"]:[];
if ( ! is_nt && ! local_err && go_on )
{
// First check if there are any NTFS partitions on the system
//
partitions_local = filter( map pentry, partitions,
``( is_ntfs_partition( pentry ) ) );
if ( size( partitions_local ) != 0 ) is_nt = true; // is NT system
}
if( !is_nt && !local_err && go_on )
{
// Then look for specific files on all FAT partitions
//
partitions_local = filter( map pentry, partitions,
``( is_fat_partition( pentry ) ) );
if ( size( partitions_local ) == 0 ) go_on = false; // not an NT system
}
// If there are FAT partitions mount them and check specific files
//
if( ! is_nt && ! local_err && go_on )
{
foreach( map pentry, partitions_local,
``{
// Now we are looping over all partitions for the current device.
// get some special values from the partition entry.
if( ! is_nt && ! local_err && go_on )
{
// build devicename.
fat_partition = pentry["device"]:"";
// mount the partition
local_ret =
(integer)SCR::Execute( .target.bash,
"/bin/mount "+fat_partition+" /mnt" );
if ( local_ret != 0 )
{
y2error( "FAT partition <%1> could not be mounted. Canceled", fat_partition );
local_err = true;
}
}
if( ! is_nt && ! local_err && go_on )
{
if ( file_exist( "/mnt/winnt/system32/ntoskrnl.exe" ) ||
file_exist( "/mnt/winnt/system32/dllcache" ) )
{
y2error( "Current Windows device <%1> is NT or 2000. Canceled", fat_partition );
is_nt = true;
}
}
// unmount the partition if was mounted
if ( !local_err ) SCR::Execute(.target.bash, "/bin/umount " + fat_partition );
}); // loop over all partitions
}
if ( local_err ) return 2;
if ( is_nt ) return 1;
else return 0;
}; // End of check_win_nt_system()
// --------------------------------------------------------------
// Renumber the logical partitions if some of them are deleted
// The returned list is sorted by partition number instead of region
define list<map> renumber_logical_partitions (list<map> partitions) ``{
partitions = sort (map a, map b, partitions, ``(a["nr"]:0 < b["nr"]:0));
integer logicals_deleted = 0;
return maplist (map pentry, partitions, ``{
if (pentry["type"]:`unknown == `logical) {
if (pentry["delete"]:false)
logicals_deleted = logicals_deleted + 1;
else
pentry = add (pentry, "nr",
pentry["nr"]:0 - logicals_deleted);
}
return pentry;
});
};
// Find unused space at the end of the extended partition
define list<integer> unused_extended_region (list<map> partitions) ``{
list<integer> extended = extended_region (partitions);
list logicals = filter (map pentry, partitions, ``(pentry["type"]:`unknown == `logical));
integer end_of_logicals = 0;
if (size (logicals) > 0)
end_of_logicals = end_of_region(logicals[size(logicals)-1,"region"]:[]);
else
end_of_logicals = start_of_region (extended);
if (end_of_logicals < end_of_region (extended))
return [ end_of_logicals, end_of_region (extended) - end_of_logicals ];
return [0, 0];
};
// Find unused space at the start of the extended partition
define list<integer> unused_logical_region (list<map> partitions) ``{
list<integer> extended = extended_region (partitions);
list logicals = filter (map pentry, partitions, ``(pentry["type"]:`unknown == `logical));
integer start_of_logicals = 0;
if (size (logicals) > 0)
start_of_logicals = start_of_region (logicals[0,"region"]:[]);
else
start_of_logicals = start_of_region (extended);
if (start_of_logicals > start_of_region (extended))
return [ start_of_region(extended), start_of_region (extended) - start_of_logicals ];
return [0, 0];
};
define integer calculate_needed_swap ()
``{
return 1024*1024*Partitions::SwapSizeMb( 0 );
};
}