home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2000-03-30 | 123.0 KB | 3,066 lines
/* ************************************************************* * * YaST2 SuSE Labs -o) * -------------------- /\\ * _\_v * www.suse.de / www.suse.com * ---------------------------------------------------------- * * Author: Michael Hager <mike@suse.de> * * Description: Partitioner for experts. * * * Purpose: * -Determing possible partitions. * -Ask the user which partition to use. * -Check the input and return error-messages. * -Writing user_settings with the selected partitions. * * user_settings: used: targets * used: architecture * * external function: get_partition_info: get a list of current partitions * check4partitions: read the disk-information * ************************************************************* $Id: inst_custom_part.ycp,v 1.46.4.3 2000/03/27 15:29:21 kkaempf Exp $ HINTS: Always use lookup( part, "delete", false) lookup( part, "create", false) instead of lookup( part, "delete") lookup( part, "create") cause delete, create are not always set to false */ { // fall through to next step if target_is NOT custom if (lookup(user_settings, "target_is", "CUSTOM") != "CUSTOM") return `auto; symbol fdisk_type = `intel; // At the moment this partitioner is for intel only string architecture = lookup( user_settings, "architecture", default_architecture); UI(``{ define FsIdToString( integer fs_id ) ``{ if ( fs_id == 0xa7) return( " NeXTSTEP "); if ( fs_id == 0xb7) return( " BSDI fs "); if ( fs_id == 0xb8) return( " BSDI swap "); if ( fs_id == 0xc1) return( " DRDOS/sec "); if ( fs_id == 0xc4) return( " DRDOS/sec "); if ( fs_id == 0xc6) return( " DRDOS/sec "); if ( fs_id == 0xc7) return( " Syrinx "); if ( fs_id == 0xdb) return( " CP/M / CTOS "); if ( fs_id == 0xe1) return( " DOS access "); if ( fs_id == 0xe3) return( " DOS R/O "); if ( fs_id == 0xe4) return( " SpeedStor "); if ( fs_id == 0xeb) return( " BeOS fs "); if ( fs_id == 0xf1) return( " SpeedStor "); if ( fs_id == 0xf4) return( " SpeedStor "); if ( fs_id == 0xf2) return( " DOS secondary "); if ( fs_id == 0xfd) return( " Linux raid "); if ( fs_id == 0xfe) return( " LANstep "); if ( fs_id == 0xff) return( " BBT "); if ( fs_id == 0x0) return( " empty "); if ( fs_id == 0x1) return( " FAT12 "); if ( fs_id == 0x2) return( " XENIX root "); if ( fs_id == 0x3) return( " XENIX usr "); if ( fs_id == 0x4) return( " FAT16 <32M "); // description for the partition typ in the patition table if ( fs_id == 0x5) return( _("Extended")); if ( fs_id == 0x6) return( " FAT16 "); if ( fs_id == 0x7) return( " HPFS/NTFS "); if ( fs_id == 0x8) return( " AIX "); if ( fs_id == 0x9) return( " AIX boot "); if ( fs_id == 0xa) return( " OS/2 boot manager"); if ( fs_id == 0xb) return( " Win95 FAT32 "); if ( fs_id == 0xc) return( " Win95 FAT32 "); if ( fs_id == 0xe) return( " Win95 FAT16 "); if ( fs_id == 0xf) return( " Win95 Erw. LBA"); if ( fs_id == 0x10) return( " OPUS "); if ( fs_id == 0x11) return( " Verst. FAT12 "); if ( fs_id == 0x12) return( " Compaq diag"); if ( fs_id == 0x14) return( " Verst. FAT16 "); if ( fs_id == 0x16) return( " Verst. FAT16 "); if ( fs_id == 0x17) return( " Verst. HPFS/NTFS"); if ( fs_id == 0x18) return( " AST Windows "); if ( fs_id == 0x1b) return( " Verst. Win95 "); if ( fs_id == 0x1c) return( " Verst. Win95 "); if ( fs_id == 0x1e) return( " Verst. Win95 "); if ( fs_id == 0x24) return( " NEC DOS "); if ( fs_id == 0x3c) return( " PartitionMagic"); if ( fs_id == 0x40) return( " Venix 80286 "); if ( fs_id == 0x41) return( " PPC PReP Boot "); if ( fs_id == 0x42) return( " SFS "); if ( fs_id == 0x4d) return( " QNX4.x "); if ( fs_id == 0x4e) return( " QNX4.x 2nd par"); if ( fs_id == 0x4f) return( " QNX4.x 3rd par"); if ( fs_id == 0x50) return( " OnTrack DM "); if ( fs_id == 0x51) return( " OnTrack DM6 Au"); if ( fs_id == 0x52) return( " CP/M "); if ( fs_id == 0x53) return( " OnTrack DM6 Au"); if ( fs_id == 0x54) return( " OnTrackDM6 "); if ( fs_id == 0x55) return( " EZ-Drive "); if ( fs_id == 0x56) return( " Golden Bow "); if ( fs_id == 0x5c) return( " Priam Edisk "); if ( fs_id == 0x61) return( " SpeedStor "); if ( fs_id == 0x63) return( " GNU HURD / Sys"); if ( fs_id == 0x64) return( " Novell Netware"); if ( fs_id == 0x65) return( " Novell Netware"); if ( fs_id == 0x70) return( " DiskSecure "); if ( fs_id == 0x75) return( " PC/IX "); if ( fs_id == 0x80) return( " Old Minix "); if ( fs_id == 0x81) return( " Minix "); if ( fs_id == 0x82) return( " Linux Swap "); if ( fs_id == 0x83) return( " Linux "); if ( fs_id == 0x84) return( " OS/2 verst. "); if ( fs_id == 0x85) return( " Linux ext."); if ( fs_id == 0x86) return( " NTFS volume se"); if ( fs_id == 0x87) return( " NTFS volume se"); if ( fs_id == 0x93) return( " Amoeba "); if ( fs_id == 0x94) return( " Amoeba BBT "); if ( fs_id == 0xa0) return( " IBM Thinkpad "); if ( fs_id == 0xa5) return( " BSD/386 "); return( "unknown" ); }; }); /*--------------------------------------------------------------------- * Convert a hard disk device name like "/dev/hda" into a SCR path * that can be used to query SCR about technical data (.disk.hda). * * Return value: device as SCR path *---------------------------------------------------------------------- */ define DevNameToScrPath ( string dev_name ) ``{ if ( substring ( dev_name, 0, 5 ) == "/dev/" ) { dev_name = substring ( dev_name, 5 ); } return ( .disk + topath ( "." + dev_name ) ); }; /*--------------------------------------------------------------------- * Check if the numer is in the format [+]<number>[kKmMgGtT] * * Returns true or false *---------------------------------------------------------------------- */ UI(``{ define IsNumber( string input ) ``{ integer n = 0; while (n < size(input)) { string erg = filterchars(substring(input, n,1), "0123456789"); _debug( erg); if (size(erg) != 1) { _debug(n); return(false); } n = n + 1; } return(true); }; }); /*--------------------------------------------------------------------- * I386: * Check if the patition-id is an extended -id * * Returns true or false *---------------------------------------------------------------------- */ define IsExtended( integer number ) ``{ // Standrd-Erw Linux-Erweiterte Win95-Erweitert if ( (number == 5) || (number == 133) || (number == 5) ) { _debug( "IS__EXTENDE YES"); return(true); } else { _debug( "IS__EXTENDE NO"); return(false); } }; /*--------------------------------------------------------------------- * Check if the numer is in the format [+]<number>[kKmMgGtT] * * Returns true or false *---------------------------------------------------------------------- */ define IsNumber( string input ) ``{ integer n = 0; while (n < size(input)) { string erg = filterchars(substring(input, n,1), "0123456789"); _debug( erg); if (size(erg) != 1) { _debug(n); return(false); } n = n + 1; } return(true); }; /*--------------------------------------------------------------------- * Check if the numer is in the format [+]<number>[kKmMgGtT] * * Returns true or false *---------------------------------------------------------------------- */ UI(``{ define IsCylNumber( string input ) ``{ if (substring( input, 0, 1) == "+") { input = substring( input, 1); } if ( !IsNumber(input)) { // check whether the last char is in "gGtTkKmMº string last_char = substring( input, size(input)-1, 1); string erg = filterchars(last_char, "kKmMgGtT"); if (size(erg) != 1) { // the last isn't in "kKmMgGtT" return( false ); } else { // the last is in "kKmMgGtT" check whether the rest is a number return( IsNumber( substring(input, 0, size(input)-1))); } } else { return( true ); } }; }); /*--------------------------------------------------------------------- * Parse the end_partition String * Input: * - start_cylinder, * - end of partition in * valid is [+]<number>[kKmMgGtT] * insert a valid string! consistency must be already checked * - size of a cylinder in byte * * Returns (endcylinder -startcylinder +1) as integer *---------------------------------------------------------------------- */ UI(``{ define ToEndRegion(string start_cyl, string end_part, integer cyl_size ) ``{ boolean is_add = false; string input = end_part; if (substring( input, 0, 1) == "+") { input = substring( input, 1); is_add = true; } if ( !IsNumber(input)) { is_add = true; // 44k is the same as +44k // take last char string last_char = substring( input, size(input)-1, 1); integer base = tointeger(substring( input, 0, size(input)-1 )); if ( last_char == "k" || last_char == "K" ) { return( (base*1024)/cyl_size +1 ); } if ( last_char == "m" || last_char == "M" ) { return( (base*1048576)/cyl_size +1 ); } if ( last_char == "g" || last_char == "G" ) { return( (base*1073741824)/cyl_size +1 ); } if ( last_char == "t" || last_char == "T" ) { return( (base*(1099511627776/cyl_size) +1 )); } y2log( .error, "Error in parsing end_cylinder" ); return( base ); } else { if (is_add) { return( tointeger(input) ); } else { return( tointeger(input)-tointeger(start_cyl)+1 ); } } }; }); /*--------------------------------------------------------------------- * Convert <number-of-bytes> to XXX.X MB or XXX.X GB or XXX.X TB * * Return value: string *---------------------------------------------------------------------- */ define ByteToHumanString ( integer number ) ``{ // column description, if disk space is not known if ( number == 0 ) return( _("unknown") ); if ( number < 1073741824 ) { // < 1 GB integer MB = number / 1048576; integer hunKB = (number - (MB * 1048576)) / 102400; if ( hunKB >= 10 ) { hunKB = 0; MB = MB+1; } return( sformat( "%1.%2 MB", MB,hunKB )); } else if ( number < 1099511627776 ) { // < 1 TB integer GB = number / 1073741824; integer hunMB = (number - (GB * 1073741824)) / 104857600; if ( hunMB >= 10 ) { hunMB = 0; GB = GB+1; } return( sformat( "%1.%2 GB", GB,hunMB )); } else { // >= 1 TB integer TB = number / 1099511627776; integer hunGB = (number - (TB * 1099511627776)) / 107374182400; if ( hunGB >= 10 ) { hunGB = 0; TB = TB+1; } return( sformat( "%1.%2 TB", TB,hunGB )); } }; /*--------------------------------------------------------------------- * tests which Partition types on a disk can be created * for Intel-I386! * * Input: map disk // (the map out of the targets map) * string dev // /dev/hda * * Return value: [ <primary_poss>, <extended_poss>, <logical_poss> ] * boolean primary_poss; // Is a primary partition possible * boolean extended_poss; // Is a extended partition possible * boolean logical_poss; // Is a logical partition possible *---------------------------------------------------------------------- * DESCRIPTION * * primary_part_is_possible = false; // can I create a primary part ? * extended_part_is_possible = false; // can I create a extended part ? * logial_part_is_possible = false; // ... * * * if (one of the partitions <disk>1 <disk>2 <disk>3 <disk>4 * is not used ) * { * primary_part_is_possible = true; * } * * if primary_part_is_possible && (no extended partition exists) * { * extended_part_is_possible = true; * } * * if (extended partition already exists) && (extended partition has * space left) * && (not more than 15 logical parts already exist) * { * logial_part_is_possible = true; * } * * * At the same time is not possible, that both "logial_part_is_possible" * and "extended_part_is_possible" are true * so we have 6 possible situations * * to show this we use * "P" for primary_part_is_possible * "E" for extended_part_is_possible * "L" for logial_part_is_possible * * "p" for primary_part_is_possible == false * "e" for extended_part_is_possible == false * "l" for logial_part_is_possible == false * * * PE : I can create a primary or exended part. * PL : Extended part. exist. I can create a primary or a logical * Pel : only a priary is possible, when the extended part. has no space left * * pE : Not possible, if "E" is possible always "P" is possible too. * pL : only a logical is possible, if together 4 primary and extended * partitions are already created * pel : no partitions are possible * *---------------------------------------------------------------------- */ define CheckCreatePossibilities( string dev, map disk ) ``{ string type = substring(dev, 5, 2); boolean extended_exists = false; symbol no_logical_cause = `no_ext; symbol no_primary_cause = `dev_full; symbol no_extended_cause = `dev_full; boolean primary_is_possible = false; boolean extended_is_possible = false; boolean logical_is_possible = false; list primary_list = filter( `part, lookup( disk, "partitions"), ``( (lookup( part, "type") == `primary) && (!lookup( part, "delete", false) ))); list extended_list = filter( `part, lookup( disk, "partitions"), ``( (lookup( part, "type") == `extended) && (!lookup( part, "delete", false) ))); list logical_list = filter( `part, lookup( disk, "partitions"), ``( (lookup( part, "type") == `logical) && (!lookup( part, "delete", false) ))); if ( (size(extended_list) + size(primary_list)) <= 3 ) { primary_is_possible = true; } if ( primary_is_possible && (size(extended_list) == 0) ) { extended_is_possible = true; } if ( size(extended_list) > 0 ) // "== 1" should also work, but ">" for safety { no_extended_cause = `already; extended_exists = true; } if ( extended_exists ) { no_logical_cause = `no_extsp; // test if extended partition has space left == a slot exists boolean slot_exist = false; // Start-End of the extended partition integer start_ext_cyl = select( lookup( select( extended_list, 0 ), "region" ), 0); integer end_ext_cyl = select( lookup( select( extended_list, 0 ), "region" ), 1) + start_ext_cyl -1; // logical_cyl_list = [ <start_cyl.firstLogPart> , <end_cyl.firstLogPart> , <start.nextLogPart> ,....., <end.lastLogPart>] // // example: input: hda5:region [255,100] hda6:region[355,100] hda7[455,100] // is al list generatated: logical_cyl_list = [255,354,355,454,455,555] // list logical_cyl_list = sort(flatten(maplist( `part, logical_list, ``([select(lookup(part, "region"), 0), select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ])))); // Look for a slot in the list of cylinders integer n = 0; if (size(logical_cyl_list) == 0 ) { // no logical partitions exist slot_exist = true; } else { repeat { if ( n == 0 ) { // first if ( select( logical_cyl_list, 0 ) != start_ext_cyl ) slot_exist = true; } else if ( n == (size(logical_cyl_list)/2)) { // last if ( select( logical_cyl_list, size(logical_cyl_list)-1 ) != end_ext_cyl ) slot_exist = true; } else { //check if between logical partition n-1 and n is a slot if ( (select( logical_cyl_list, 2*n-1 )+1) != (select( logical_cyl_list, 2*n ) )) slot_exist = true; } n = n+1; } until ( n == ( (size(logical_cyl_list)/2 +1)) || slot_exist ); } if (slot_exist) { no_logical_cause = `to_many; if ( type == "hd" ) // EIDE supports 64 partitions { if (size(logical_cyl_list)/2 < 60 ) logical_is_possible = true; } if ( type == "sd" ) // SCSI supports 16 partitions { if (size(logical_cyl_list)/2 < 12 ) logical_is_possible = true; } else { logical_is_possible = true; } } } return( [primary_is_possible, extended_is_possible, logical_is_possible, no_primary_cause, no_extended_cause, no_logical_cause ]); }; /*--------------------------------------------------------------------- * Find bigest slot * return [start, end] or nil *--------------------------------------------------------------------- */ define GetSlot( string dev, map disk ) ``{ string type = substring(dev, 5, 2); list global_list = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") != `logical) && !lookup( part, "delete", false) )); list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0), select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ])))); // Look for a slot in the list of cylinders integer n = 0; integer start_cyl = 0; integer end_cyl = lookup( disk, "cyl_count" )-1; integer sl_start = 0; integer sl_end = 0; integer curr_start = 0; integer curr_end = 0; boolean slot_exist = false; if (size(global_cyl_list) == 0 ) { // no partition exist return( [start_cyl, end_cyl]); } else { repeat { if ( n == 0 ) { // first curr_start = start_cyl-1; curr_end = select( global_cyl_list, 0 ); } else if ( n == (size(global_cyl_list)/2)) { // last curr_start = select( global_cyl_list, size(global_cyl_list)-1); curr_end = end_cyl+1; } else { //check if between global partition n-1 and n is a slot curr_start = select( global_cyl_list, 2*n-1 ); curr_end = select( global_cyl_list, 2*n ); } if ( curr_start+1 != curr_end ) { slot_exist = true; _debug( "A Slot at: ", curr_start, curr_end ); if ( (curr_end - curr_start -2) >= (sl_end - sl_start) ) { sl_start = curr_start+1; sl_end = curr_end-1; } } _debug("SLOT-", slot_exist, curr_start, curr_end, n ); n = n+1; } until ( n == ( (size(global_cyl_list)/2 +1))); } if (slot_exist) { return( [sl_start, sl_end] ); } else { return(nil); } }; /*--------------------------------------------------------------------- * test primary and extended slot * return [start, end] or nil * Input: start_cyl of the tested slot, /dev/hda1, diskmap * return [max-end_cyl] or "nil" if its no valid start_cyl * todo: GetSlo TestSlot should be one function *--------------------------------------------------------------------- */ UI(``{ define TestSlot( integer slot_start_cyl, string dev, map disk ) ``{ string type = substring(dev, 5, 2); list global_list = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") != `logical) && !lookup( part, "delete", false) )); list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0), select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ])))); // Look for a slot in the list of cylinders integer n = 0; integer start_cyl = 0; integer end_cyl = lookup( disk, "cyl_count" )-1; integer sl_start = 0; integer sl_end = 0; integer curr_start = 0; integer curr_end = 0; boolean slot_exist = false; if (size(global_cyl_list) == 0 ) { _debug( "Testing Slot : disk empty"); if ( start_cyl <= slot_start_cyl && slot_start_cyl <= end_cyl ) return( end_cyl ); } else { repeat { if ( n == 0 ) { // first curr_start = start_cyl-1; curr_end = select( global_cyl_list, 0 ); } else if ( n == (size(global_cyl_list)/2)) { // last curr_start = select( global_cyl_list, size(global_cyl_list)-1); curr_end = end_cyl+1; } else { //check if between global partition n-1 and n is a slot curr_start = select( global_cyl_list, 2*n-1 ); curr_end = select( global_cyl_list, 2*n ); } _debug( "Testing Slot < x < ", curr_start, curr_end ); if ( curr_start < slot_start_cyl && slot_start_cyl < curr_end ) { // If the slot was found ... _debug( "X Slot at: ", curr_start, curr_end ); ////////////////// return( curr_end-1 ); ////////////////// } _debug("SLOT-", slot_exist, curr_start, curr_end, n ); n = n+1; } until ( n == ( (size(global_cyl_list)/2 +1))); } return(nil); }; }); /*--------------------------------------------------------------------- * Find bigest slot for logical * return [start, end] or nil /*--------------------------------------------------------------------- */ define GetLogicalSlot( string dev, map disk ) ``{ string type = substring(dev, 5, 2); list global_list = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `logical) && !lookup( part, "delete", false) )); map|void extended = find( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `extended) && !lookup( part, "delete", false) )); ////////////////////////////////// if (extended == nil ) return(nil); ////////////////////////////////// list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0), select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ])))); // Look for a slot in the list of cylinders integer n = 0; integer start_cyl = tointeger( select(lookup( extended, "region"),0) ); integer end_cyl = start_cyl + tointeger(select(lookup( extended, "region"), 1)) -1; integer sl_start = 0; integer sl_end = 0; integer curr_start = 0; integer curr_end = 0; boolean slot_exist = false; if (size(global_cyl_list) == 0 ) { // no partition exist return( [start_cyl, end_cyl]); } else { repeat { if ( n == 0 ) { // first curr_start = start_cyl-1; curr_end = select( global_cyl_list, 0 ); } else if ( n == (size(global_cyl_list)/2)) { // last curr_start = select( global_cyl_list, size(global_cyl_list)-1); curr_end = end_cyl+1; } else { //check if between global partition n-1 and n is a slot curr_start = select( global_cyl_list, 2*n-1 ); curr_end = select( global_cyl_list, 2*n ); } if ( curr_start+1 != curr_end ) { slot_exist = true; _debug( "A Slot at: ", curr_start, curr_end ); if ( (curr_end - curr_start -2) >= (sl_end - sl_start) ) { sl_start = curr_start+1; sl_end = curr_end-1; } } _debug("SLOT-", slot_exist, curr_start, curr_end, n ); n = n+1; } until ( n == ( (size(global_cyl_list)/2 +1))); } if (slot_exist) { return( [sl_start, sl_end] ); } else { return(nil); } }; /*--------------------------------------------------------------------- * Check slot for logical partition * Input: start_cyl of the tested slot, /dev/hda5, diskmap, in edit_mode or create_mode * * return [max-end_cyl] or nil if its no valisd start_cyl * * todo: GetLogicalSlot TestLogicalSlot should be one function *--------------------------------------------------------------------- */ UI(``{ define TestLogicalSlot( integer slot_start_cyl, string dev, map disk) ``{ string type = substring(dev, 5, 2); list global_list = filter( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `logical) && !lookup( part, "delete", false) )); map extended = find( `part, lookup( disk, "partitions"), ``( (lookup(part, "type") == `extended) && !lookup( part, "delete", false) )); list global_cyl_list = sort(flatten(maplist( `part, global_list, ``([select(lookup(part, "region"), 0), select(lookup(part, "region"), 0) + select(lookup(part, "region"), 1) -1 ])))); // Look for the slot in the list of cylinders integer n = 0; integer start_cyl = tointeger( select(lookup( extended, "region"),0) ); integer end_cyl = start_cyl + tointeger(select(lookup( extended, "region"), 1)) -1 ; integer sl_start = 0; integer sl_end = 0; integer curr_start = 0; integer curr_end = 0; boolean slot_exist = false; if (size(global_cyl_list) == 0 ) { if ( start_cyl <= slot_start_cyl && slot_start_cyl <= end_cyl ) return( end_cyl ); } else { repeat { if ( n == 0 ) { // first curr_start = start_cyl-1; curr_end = select( global_cyl_list, 0 ); } else if ( n == (size(global_cyl_list)/2)) { // last curr_start = select( global_cyl_list, size(global_cyl_list)-1); curr_end = end_cyl+1; } else { //check if between global partition n-1 and n is a slot curr_start = select( global_cyl_list, 2*n-1 ); curr_end = select( global_cyl_list, 2*n ); } _debug( "Testing Slot < x < ", curr_start, curr_end ); if ( curr_start < slot_start_cyl && slot_start_cyl < curr_end ) { // If the slot was found ... _debug( "X Slot at: ", curr_start, curr_end ); ////////////////// return( curr_end -1); ////////////////// } _debug("SLOT-", slot_exist, curr_start, curr_end, n ); n = n+1; } until ( n == ( (size(global_cyl_list)/2 +1))); } return(nil); }; }); /*--------------------------------------------------------------------- * Fill the selection box with ID 'selbox_id' inside widget tree * 'widget' with disk and partition info from 'all_disks'. * * Return value: * term contents = `VBox(`Label("Today's menu in the kanteen"), * `Table(`header("Device", "Start", "End", "Size", "F", "Type", "Mount"), * [ * `item(`id(1), "/dev/hda", "1", "1115", "8.5 GB", " ", "Seagate ST 48012", " "), * `item(`id(2), " /dev/hda1", "1", "65", "509.8 MB", " ", "FAT16", " "), * `item(`id(3), " /dev/hda2", "66", "150", "666.7 MB", " ", "NTFS", " "), * `item(`id(4), " /dev/hda3", "301","1024", "5.5 GB", " ", "Extended", " "), * `item(`id(5), " /dev/hda5", "301","302", "7.8 MB", "F", "Linux ", "/boot") * ] )) ; *---------------------------------------------------------------------- */ define FillPartitionList ( map targets ) ``{ list table_input = []; //boolean log_mode = true; // more logging info in main dialog!! boolean log_mode = false; foreach ( `disk_dev_name, `disk, targets, ``{ integer cyl_count = lookup ( disk, "cyl_count", 0 ); integer cyl_size = lookup ( disk, "cyl_size", 1000000 ); string vendor = lookup ( disk, "vendor", "" ); string model = lookup ( disk, "model", "" ); if ( (model != "") && (vendor != "") ) vendor = vendor + "-" + model; else vendor = vendor + model; // entry in column "Type" for a unknown disk if ( vendor == "" ) vendor = sformat( UI(_("DISK %1")) , substring( disk_dev_name, 5 )); // Insert line for the entire disk into selection box widget term a = `item(`id(disk_dev_name), disk_dev_name, 0, cyl_count-1, ByteToHumanString(cyl_count * cyl_size), " ", vendor, "" ); table_input = add( table_input, a ); list partitions = lookup ( disk, "partitions" ); foreach ( `partition, partitions, ``{ if ( !lookup ( partition, "delete", false ) || log_mode ) { string id = ""; if ( lookup ( partition, "nr") < 10 ) { id = sformat( "0%2.%1", disk_dev_name, lookup ( partition, "nr")); } else { id = sformat( "%2.%1", disk_dev_name, lookup ( partition, "nr")); } string part_dev_name = sformat( "%1%2", disk_dev_name, lookup ( partition, "nr")); integer start_cyl = select ( lookup ( partition, "region"), 0 ); integer nb_cyl = select ( lookup ( partition, "region"), 1 ); symbol type = lookup ( partition, "type" ); boolean format = lookup ( partition, "format", false ); symbol used_fs = lookup ( partition, "used_fs", `unknown ); string mount_point = lookup ( partition, "mount", "" ); string filesystem_name = ""; if (lookup ( partition, "type") == `pdisk) { filesystem_name = lookup ( partition, "fstype", "?"); } else { filesystem_name = UI(`FsIdToString( lookup ( partition, "fsid" ))); } if ( format && (used_fs == `ext2) ) filesystem_name = filesystem_name + " (Ext2) "; if ( format && (used_fs == `reiser)) filesystem_name = filesystem_name + " (ReiserFS) "; string format_flag = ""; if ( format ) format_flag = "F"; if ( log_mode ) { string ori_str = ""; void|boolean del = lookup ( partition, "delete" ); void|boolean cre = lookup ( partition, "create" ); void|integer ori = lookup ( partition, "ori_nr" ); if ( del == nil ) format_flag = format_flag + " dn"; if ( del == true ) format_flag = format_flag + " dT"; if ( del == false ) format_flag = format_flag + " dF"; if ( cre == nil ) format_flag = format_flag + " cn"; if ( cre == true ) format_flag = format_flag + " cT"; if ( cre == false ) format_flag = format_flag + " cF"; if ( ori != nil ) ori_str = sformat( " o%1 ", ori ); if ( ori == nil ) ori_str = " o- "; format_flag = format_flag + ori_str; } integer bytes_of_part = ( nb_cyl ) * cyl_size; // Insert line for this partition into selection box widget term a = `item(`id(id), part_dev_name, start_cyl, start_cyl + nb_cyl - 1, ByteToHumanString(bytes_of_part), format_flag, filesystem_name, mount_point ); table_input = add( table_input, a ); } else { // as deted marked // _debug( "ddddddddddddd----"); } } ); } ); return sort( `lineA, `lineB, table_input, ``( { return( select(lineA, 1) <= select(lineB, 1 )); })); }; /*--------------------------------------------------------------------- * Initialize Partitiontable: * * - all really existing partition get a ori_nr * We need this number, when a logical partition is deleted and * other logical partition change their number * * - delete pseudo partitions with `free from target_partitioner * * - mark swap-partition with pseudo Mountpoint swap *---------------------------------------------------------------------- */ define InitTargets ( map targets ) ``{ foreach( `disk_dev_name, `disk, targets, ``{ // only really existing! list partitions = lookup ( disk, "partitions"); partitions = filter( `partition, partitions, ``( lookup(partition, "type", `free) != `free ) ); partitions = maplist( `partition, partitions, ``( { map result = partition; if ( lookup(partition, "fsid", 131) == 130 ) { result = add( result, "mount", "swap"); } if ( lookup(partition, "ori_nr") == nil ) { result = add( result, "ori_nr", lookup(partition, "nr")); } _debug( "WW", result); return ( result ); })); disk = add( disk, "partitions", partitions ); targets = add( targets, disk_dev_name, disk ); }); return targets; }; /*--------------------------------------------------------------------- * Checks if the mountpoint is valid * - /proc /mnt /lost+found contain /var/adm/mount are not allowd * - double entries are not allowed ( mountpoints with no / and "" are always allowed ) * *---------------------------------------------------------------------- */ UI(``{ define check_mount_point( map targetMap, string mount ) ``{ boolean allowed = true; if ( mount != "" && mount != "swap" ) { foreach( `disk, `diskinfo, targetMap, ``{ list part_info = lookup( diskinfo, "partitions" ); foreach( `part, part_info, ``{ if ( lookup( part, "delete", false) == false ) { // all valid partitions if ( lookup( part, "mount", "") == mount ) allowed = false; } }); }); if ( allowed == false ) { DisplayMessage(_("The mount point is already in use, please choose another moint point")); } else { if ( contains([ "/proc", "/dev", "/mnt", "var/adm/mnt", "/lost+found" ], mount) ) { allowed = false; DisplayMessage(_("You cannot use one of the following mountpoints: /proc, /dev, /mnt, var/adm/mnt, /lost+found")); } else if ( substring( mount, 0, 1 ) != "/" ) { allowed = false; DisplayMessage(_("Your mountpoint must start with a \"/\" ")); } } } else { allowed = true; } return( allowed ); }; }); /*--------------------------------------------------------------------- * Display "Create a partition Dialog" * * Input: * string title, * boolean format, * integer filesystem_id, * string start_cyl, * string end_part, * string mount_point, * symbol type, * string dev, * map disk, CAUTION: in Edit-Mode, the edited partion, must not be in this map!! * integer cyl_size cylinder size * targetMap CAUTION: in Edit-Mode, the edited partion, must not be in this map! * * return: nil bei cancel * [fsid,format,mount,start_cyl,end_cyl, used_fs] *---------------------------------------------------------------------- */ UI(``{ define EditOrCreatePartDlg(string title, boolean format, integer filesystem_id, string start_cyl, string end_part, string mount_point, symbol type, string dev, map disk, integer cyl_size, symbol used_fs, map targetList ) ``{ // helptext for popup create partition line 1 of 6 string helptextCR = _("<p>First, please choose the type of the new partiton and whether this partition should be formatted or not.</p>" ); // helptext for popup create partition line 2 of 6 helptextCR = helptextCR + _("<p>Then you must enter the mount point ( /, /boot, /usr, /var ... )</p>" ); // helptext for popup create partition line 3 of 6 helptextCR = helptextCR + _("Now you can enter the location of the new partition on your hard disk. "); // helptext for popup create partition line 4 of 6 helptextCR = helptextCR + _("<p>Please enter the starting cylinder number of the partition."); // helptext for popup create partition line 5 of 6 helptextCR = helptextCR + _("After that you can either specify an ending cylinder number or an offset from the first cylinder (e.g +66)."); // helptext for popup create partition line 6 of 6 helptextCR = helptextCR + _("It is also possible to specify the size of the partition directly (e.g. +100M or +20000K))</p>"); OpenDialog( `opt(`decorated ), `VBox(`Heading(title), `Label(""), `HBox( /// left side `RichText( helptextCR ), /// right side `VBox( // popup create partition: Framedescription Typ of Filesystem `Frame ( _("Type"), `RadioButtonGroup(`id(`fs), `VBox( // popup create partition: Typ of Filesystem: Linux native `Left(`RadioButton(`id(`reiser),`opt(`notify), // popup create partition: here you choose the type of the // filesystem/ Data with ReiserFS/ Data with Ext2 or / Swap _("Data with &ReiserFS"), (filesystem_id == 131) && (used_fs == `reiser) )), `Left(`RadioButton(`id(`ext2),`opt(`notify), // popup create partition: here you choose the type of the filesystem/ // Data with ReiserFS/ Data with Ext2 or / Swap _("Data with &Ext2"), (filesystem_id == 131) && (used_fs == `ext2 ))), // popup create partition: Typ of Filesystem: Linux Swap `Left(`RadioButton(`id(`swap),`opt(`notify), _("&Swap") , (filesystem_id == 130)) ) ) ) ), `Label(""), // popup create partition: Framedescription "Format partition or not" `Frame ( substring(_("2:Format"),2), `RadioButtonGroup(`id(`format), `VBox( // popup create partition: Dont format partition `Left(`RadioButton(`id(false),_("Do ¬ format"), !format )), // popup create partition: Format partition (Vocative) `Left(`RadioButton(`id(true), _("&Format"), format )) ) ) ), `Label(""), // popup create partition: Framedescription Choose Mountpoint `Frame ( _("Mount Point"), // popup create partition: Description Inputfield `TextEntry(`id(`mount_point), _("&Mount Point:")) ), `Label(""), // popup create partition: Framedescription Start/Endcylinder `Frame ( _("Size"), `VBox( // popup create partition: Description Inputfield `TextEntry(`id(`start_cyl), _("S&tart cylinder:")), // popup create partition: Description Inputfield +9M means add 9 MB `TextEntry(`id(`end_part), _("E&nd: ( 9 or +9M or +9G )")) ) ) ), `Label(" ") ), `Label(""), `HBox( // popup create partition: `PushButton(`id(`ok), `opt(`default), _("&OK")), // popup create partition: `PushButton(`id(`cancel), _("&Cancel")) ) ) ); string user_mount_point = ""; ChangeWidget(`id(`start_cyl), `Value, start_cyl); ChangeWidget(`id(`end_part), `Value, end_part); SetFocus(`id(`start_cyl)); // if the user choose swap mount, mount swap should be displayed if (filesystem_id == 130) { ChangeWidget(`id(`mount_point), `Value, "swap"); mount_point = "swap"; ChangeWidget(`id(`mount_point), `Enabled, false ); user_mount_point = ""; } else { ChangeWidget(`id(`mount_point), `Value, mount_point); ChangeWidget(`id(`mount_point), `Enabled, true ); user_mount_point = mount_point; } boolean input_is_ok = false; map return_value = $[]; symbol doit_int = `ok; symbol doit = `cancel; repeat { //------------------------------- // Check the User input / change popup ... //------------------------------- doit_int = UserInput(); if (doit_int == `cancel) doit = `cancel; else if (doit_int == `ok) doit = `ok; else doit = `retry; if ( doit != `cancel ) { return_value = $[]; //------------------------------------------------------------ // Read the format-type and y/n symbol format_id = QueryWidget(`id(`fs), `CurrentButton); if ( format_id != `swap ) return_value = add( return_value, "fsid", 131 ); if ( format_id == `swap ) return_value = add( return_value, "fsid", 130 ); if ( format_id == `ext2 ) return_value = add( return_value, "used_fs", `ext2 ); if ( format_id == `reiser ) return_value = add( return_value, "used_fs", `reiser ); return_value = add( return_value, "format", QueryWidget(`id(`format), `CurrentButton)) ; return_value = add( return_value, "mount", QueryWidget(`id(`mount_point), `Value)) ; return_value = add( return_value, "start_cyl", QueryWidget(`id(`start_cyl), `Value)) ; return_value = add( return_value, "end_part", QueryWidget(`id(`end_part), `Value)) ; ////////////////////////////////////////////////////////////// // if the user choose swap no mount_poit should be displayed .. if (QueryWidget(`id(`fs), `CurrentButton) == `swap) { mount_point = "swap"; ChangeWidget(`id(`mount_point), `Value, "swap"); ChangeWidget(`id(`mount_point), `Enabled, false ); } else { mount_point = QueryWidget(`id(`mount_point), `Value); if (mount_point != "swap" ) user_mount_point = mount_point; // notice last user_input if (mount_point == "swap" ) mount_point = user_mount_point; // set last user_input ChangeWidget(`id(`mount_point), `Value, mount_point); ChangeWidget(`id(`mount_point), `Enabled, true ); } if ( doit == `ok ) { ////////////////////////////////////////////////////////////// // Check if the user input for start und end cyl are valid list ret = TestStartEndCyl( lookup(return_value, "start_cyl"), lookup(return_value, "end_part"), dev, disk, type, cyl_size ); if (select( ret, 0) == `error ) input_is_ok = false; if (select( ret, 0) == `ok ) input_is_ok = true; if (select( ret, 0) == `max ) { input_is_ok = true; return_value = add( return_value, "end_part", select( ret, 1)); } ////////////////////////////////////////////////////////////// // Check if the user has a reiserfs with not enough space if ( input_is_ok && (format_id == `reiser) ) { integer part_size = ( tointeger(select( ret, 1)) - tointeger(lookup(return_value, "start_cyl")) +1 ) * cyl_size; _debug( "UUUUUUUUUUU", part_size ); if ( part_size < 60000000 ) { DisplayMessage(_("Your partition is too small, to use ReiserFS! ReiserFS is a journaling filesystem, and the storage of the journal needs already about 30 MB space. So please use ReiserFS only with bigger partitions.")); input_is_ok = false; } } ////////////////////////////////////////////////////////////// // Check if the user input for mount point are valid if ( input_is_ok ) { string user_input_mount = lookup(return_value, "mount", ""); input_is_ok = check_mount_point( targetList, user_input_mount); } } } } until ( (doit == `ok && input_is_ok) || doit == `cancel ); CloseDialog(); if ( doit == `cancel ) { return( nil ); } else { return( return_value ); } }; }); /*-------------------------------------------------------------------------------------------- * * Now check start an endcylinder * caution: there is no differenc in edit and create cause the partion, which is to edited, * is not in the disk map! * * Check: * A. Is start_cyl ist a number? no-> try again * B. is start_cyl valid ( can the partition start there?) no -> try again * (when this is tested, the maximal possible end cylinder is computed, too) * C. Now we check the syntax of the endCylinder * D. If the syntax is valid, the requested end cylinder is checked * E. If it is not valid, the user gets a popup and the maximal possible end cylinder is set * * returns [<symbol>, <value>] * * [`ok, <effektive end cyl>] * [`max, <max-value as str> ] // case E * [`error, 0] *--------------------------------------------------------------------------------------------- */ UI(``{ define TestStartEndCyl( string str_start_cyl, string str_end_part, string dev, map disk, symbol type, integer cyl_size ) ``{ void|integer max_end_cyl = 0; string max_end_str = ""; symbol input = `ok; integer int_start_cyl = tointeger(str_start_cyl); integer int_end_cyl = 0; ////////////////////////////////// STEP A //////////////////////////////////////////////// if (!IsNumber( str_start_cyl )) { input = `error; DisplayMessage(_("Wrong input for the start of the partition, \nyou must must enter the start cylinder (e.g. 77).")); } else { ////////////////////////////// STEP B //////////////////////////////////////////////// integer int_start_cyl = tointeger(str_start_cyl); if ( type == `logical ) max_end_cyl = TestLogicalSlot( int_start_cyl, dev, disk ); else max_end_cyl = TestSlot( int_start_cyl, dev, disk ); // primary && extended if ( max_end_cyl == nil ) { DisplayMessage(_("The start cylinder is not valid. Please check again")); input = `error; } if ( input == `ok ) { ////////////////////////// STEP C //////////////////////////////////////////////// if (!IsCylNumber(str_end_part)) { input = `error; DisplayMessage(_("Wrong input for the end of the partition.\n st enter the endcylinder (e.g. 77) or an offset (e.g.+122) specify the size of the partition directly (e.g. +100M or +1GB )")); } else { ////////////////////// STEP D //////////////////////////////////////////////// int_end_cyl = int_start_cyl + ToEndRegion( str_start_cyl, str_end_part, cyl_size ) -1; if ( int_end_cyl > max_end_cyl || int_end_cyl < int_start_cyl) { ////////////////// STEP E //////////////////////////////////////////////// DisplayMessage(_("CAUTION: The value of the end cylinder was not valid. \nYaST2 had inserted the maximum \npossible value")); max_end_str = sformat("%1", max_end_cyl); input = `max; } } } } // END Check if ( input == `ok ) return( [`ok, int_end_cyl ]); if ( input == `max ) return( [`max, max_end_str ]); // if ( input == `error ) return( [`error, 0]); }; }); /*--------------------------------------------------------------------- * Display "Create a extended partition Dialog" * * return: nil bei cancel * [fsid,format,mount,start_cyl,end_cyl] bei ok * *---------------------------------------------------------------------- */ UI(``{ define CreateEditExtendedPartDlg(string title, boolean format, integer filesystem_id, string start_cyl, string end_part, string mount_point, symbol type, string dev, map disk, integer cyl_size, boolean edit ) ``{ // helptext for popup create extended partition line string helptextCR = _("<p>Please enter the starting cylinder number of the partition. After that you can either specify an ending cylinder number or an offset from the first cylinder (e.g +66). It is also possible to specify the size of the partition directly (e.g. +2G or +100M or +20000K)</p>"); OpenDialog( `opt(`decorated ), `VBox(`Heading(title), `Label(""), `HBox( /// left side `RichText( helptextCR ), /// right side // popup create partition: Framedescription Start/Endcylinder `Frame ( _("Size"), `VBox( // popup create partition: Description Inputfield `TextEntry(`id(`start_cyl), _("S&tart cylinder:")), // popup create partition: Description Inputfield +9M means add 9 MB `TextEntry(`id(`end_part), _("E&nd: ( 9 or +9M or +9G )")) ) ) ), `Label(""), `HBox( // popup create partition: `PushButton(`id(`ok), `opt(`default), _("&OK")), // popup create partition: `PushButton(`id(`cancel), _("&Cancel")) ) ) ); ChangeWidget(`id(`start_cyl), `Value, start_cyl); ChangeWidget(`id(`end_part), `Value, end_part); SetFocus(`id(`start_cyl)); boolean input_is_ok = false; map return_value = $[]; symbol doit = `cancel; repeat { //------------------------------- // Check the User input //------------------------------- doit = UserInput(); if ( doit != `cancel ) { return_value = $[]; return_value = add( return_value, "fsid", filesystem_id); return_value = add( return_value, "format", format); return_value = add( return_value, "mount", mount_point); return_value = add( return_value, "start_cyl", QueryWidget(`id(`start_cyl), `Value)) ; return_value = add( return_value, "end_part", QueryWidget(`id(`end_part), `Value)) ; input_is_ok = true; ////////////////////////////////////////////////////////////// // Check if the user input for start und end cyl are valid list ret = TestStartEndCyl( lookup(return_value, "start_cyl"), lookup(return_value, "end_part"), dev, disk, type, cyl_size ); if (select( ret, 0) == `error ) input_is_ok = false; if (select( ret, 0) == `ok ) input_is_ok = true; if (select( ret, 0) == `max ) { input_is_ok = true; return_value = add( return_value, "end_part", select( ret, 1)); } } } until (input_is_ok || doit == `cancel); //------------------------------------------------------------------------------------ // Check if the start end cylinder are changed: PopUp // todo change logical cylinders //------------------------------------------------------------------------------------ if ( doit != `cancel && ( lookup(return_value, "start_cyl") > start_cyl || lookup(return_value, "end_part") != end_part )) { DisplayMessage(_("Caution: You have changed the start/end cylinders. Please make sure that all logical partitions \nfit into this new extended partition.")); } CloseDialog(); if ( doit == `cancel ) { return( nil ); } else { return( return_value ); } }; }); /*--------------------------------------------------------------------- * EditDialog for a already existing Partitions *--------------------------------------------------------------------- * targetMap CAUTION: in Edit-Mode, the edited partion, must not be in this map! */ UI(``{ define ExistingPartitionDlg(string title, boolean format, integer filesystem_id, string start_cyl, string end_part, string mount_point, map disk, map targetList, symbol used_fs, integer cyl_size, boolean pdisk_disk ) ``{ // helptext for popup edit already existing partition line 1 of 3 string helptextCR = _("<p>For an already existing partition you can only change the mount point and format.</p>" ); // helptext line 2 of 3 helptextCR = helptextCR + _("<p>If you want to change the type or the start/end cylinder, you must delete this partition and then create a new one with the new parameters. All data in this partition will be LOST!</p>" ); OpenDialog( `opt(`decorated ), `VBox(`Heading(title), `Label(""), `HBox( /// left side `HWeight( 66, `RichText( helptextCR )), /// right side `HWeight( 33, `VBox( `Top( `HBox( // popup edit existing partition: Description `Left(`Label( _("Type of filesystem: ") // popup edit existing partition: Description + _("\nStart cylinder:") // popup edit existing partition: Description + _("\nEnd cylinder: ") )), `Left(`Label( FsIdToString( filesystem_id ) + "\n " + start_cyl + "\n " + end_part )) )), // popup edit existing partition: Description to edit Mount Point `Top(`TextEntry(`id(`mount_point), _("&Mount Point:"))), // popup edit existing partition: Framedescription to Format the disk y/n `Top(`Frame ( substring(_("2:Format"),2), `RadioButtonGroup(`id(`format), `VBox( // popup edit existing partition: Selection "Do not format" `Left(`RadioButton(`id(`unknown), _("Do ¬ format"), !format )), // popup edit existing partition: Selection "Format" `Left(`RadioButton(`id(`reiser), _("Format with &ReiserFS"), (format && (filesystem_id == 131) && (used_fs == `reiser)) )), // popup edit existing partition: Selection "Format" `Left(`RadioButton(`id(`ext2), _("Format with &Ext2"), (format && (filesystem_id == 131) && (used_fs == `ext2)) )), `Left(`RadioButton(`id(`swap), _("Format &Swap"), (format && (filesystem_id == 130)) )) ) ) ) ) )) ), `Label(""), `HBox( // popup edit existing partition: OK `PushButton(`id(`ok), `opt(`default), _("&OK")), // popup edit existing partition: Cancel `PushButton(`id(`cancel), _("&Cancel")) ) ) ); // if the user choose swap .. if (filesystem_id == 130) { ChangeWidget(`id(`mount_point), `Value, "swap"); ChangeWidget(`id(`reiser), `Enabled, false ); ChangeWidget(`id(`ext2), `Enabled, false ); } else { ChangeWidget(`id(`mount_point), `Value, mount_point); ChangeWidget(`id(`swap), `Enabled, false ); } if (filesystem_id != 130 && filesystem_id != 131) { ChangeWidget(`id(`unknown), `Enabled, false ); ChangeWidget(`id(`reiser), `Enabled, false ); ChangeWidget(`id(`ext2), `Enabled, false ); ChangeWidget(`id(`swap), `Enabled, false ); } if ( pdisk_disk == true ) { ChangeWidget(`id(`unknown), `Enabled, false ); ChangeWidget(`id(`reiser), `Enabled, false ); ChangeWidget(`id(`ext2), `Enabled, false ); ChangeWidget(`id(`swap), `Enabled, false ); } boolean input_is_ok = false; map return_value = $[]; symbol doit = `cancel; repeat { //------------------------------- // Check the User input //------------------------------- doit = UserInput(); if ( doit != `cancel ) { input_is_ok = true; return_value = $[]; return_value = add( return_value, "fsid", filesystem_id) ; return_value = add( return_value, "used_fs", QueryWidget(`id(`format), `CurrentButton)) ; return_value = add( return_value, "mount", QueryWidget(`id(`mount_point), `Value)) ; return_value = add( return_value, "start_cyl", start_cyl) ; return_value = add( return_value, "end_part", end_part) ; if ( QueryWidget(`id(`format), `CurrentButton) == `unknown ) { return_value = add( return_value, "format", false ); } else { return_value = add( return_value, "format", true ); } if ( QueryWidget(`id(`format), `CurrentButton) == `swap ) { // todo: should be `swap, but I have now not the time to test this // this should be removes after the release return_value = add( return_value, "used_fs", `unknown ); } ////////////////////////////////////////////////////////////// // Check if the user has a reiserfs with not enough space if ( input_is_ok && ( lookup(return_value, "used_fs") == `reiser) ) { integer part_size = (tointeger(end_part) - tointeger(start_cyl) +1) * cyl_size; _debug( "UUUUUUUUUUU", part_size ); if ( part_size < 60000000 ) { DisplayMessage( _("Your partition is too small, to use ReiserFS! ReiserFS is a journaling filesystem, and the storage of the journal needs already about 30 MB space. So please use ReiserFS only with bigger partitions." )); input_is_ok = false; } } if ( input_is_ok ) { if (filesystem_id == 130) { ////////////////////////////////////////////////////////////// // Check swap mount point string user_input_mount = lookup(return_value, "mount", ""); if ( (user_input_mount != "") && (user_input_mount != "swap") ) { DisplayMessage( _("\ You have entered an invalid mountpoint. For a swap partition, only two mountpoints are permitted. - If you leave this field empty, the swap partition will NOT be used. - The entry \"swap\" means, that the swap partition will be used.")); input_is_ok = false; } } else { ////////////////////////////////////////////////////////////// // Check if the user input formount point are valid string user_input_mount = lookup(return_value, "mount", ""); input_is_ok = check_mount_point( targetList, user_input_mount); } } } } until (input_is_ok || doit == `cancel); CloseDialog(); if ( doit == `cancel ) { return( nil ); } else { return( return_value ); } }; }); /*--------------------------------------------------------------------- * Dialog choose disk * return /dev/xxx or nil if cancel *--------------------------------------------------------------------- */ UI(``{ define ChooseDisk( map targetMap ) ``{ // Header Choose disk dialog term diskgroup = `VBox(); list disks = []; integer n = 0; foreach ( `dev, `disk, targetMap, ``{ diskgroup = add ( diskgroup, `Left( `RadioButton( `id( dev ), dev, n == 0 ) ) ); n = n + 1; } ); foreach ( `dev, `disk, targetMap, ``{ disks = add ( disks, dev ); } ); if (size(disks) != 1 ) { OpenDialog( `opt(`decorated), `VBox(`Heading(_("On which disk do you want to create the partition?") ), `Label(""), `RadioButtonGroup( `id(`choosedisk), diskgroup ), `Label(""), `HBox( // popup edit existing partition: OK `PushButton(`id(`ok), `opt(`default), _("&OK")), // popup edit existing partition: Cancel `PushButton(`id(`cancel), _("&Cancel")) ) ) ); any ret = UserInput(); if (ret == `cancel) { CloseDialog(); return(nil); } else { ret = QueryWidget(`id(`choosedisk), `CurrentButton); CloseDialog(); return(ret); } } else { // if there is only one disk: no return( select( disks, 0 ) ); } }; }); /*--------------------------------------------------------------------- * Dialog choose primary extended or logical Partition * Input "PL", "PE" or "PEL" * return `primary or `logical or `extended or `none *--------------------------------------------------------------------- */ UI(``{ define ChoosePart( string usage ) ``{ term PL = `VBox( `Left( `RadioButton( `id(`primary ), _("&Primary partition"), true )), `Left( `RadioButton( `id(`logical ), _("&Logical partition"), false )) ); term PE = `VBox( `Left( `RadioButton( `id(`primary ), _("&Primary partition"), true )), `Left( `RadioButton( `id(`extended ), _("&Extended partition"), false )) ); term PEL = `VBox( `Left( `RadioButton( `id(`primary ), _("&Primary partition"), true )), `Left( `RadioButton( `id(`logical ), _("&Logical partition"), false )), `Left( `RadioButton( `id(`extended ), _("&Extended partition"), false )) ); term current = PEL; // default if ( usage == "PL" ) current = PL; if ( usage == "PE" ) current = PE; OpenDialog( `opt(`decorated ), `VBox(`Heading(_("Which type of partition do you want to create?") ), `Label(""), `RadioButtonGroup( `id(`choosePL), current ), `Label(""), `HBox( // popup edit existing partition: OK `PushButton(`id(`ok), `opt(`default), _("&OK")), // popup edit existing partition: Cancel `PushButton(`id(`cancel), _("&Cancel")) ) ) ); any ret = UserInput(); if (ret == `cancel) { CloseDialog(); return(`none); } else { ret = QueryWidget(`id(`choosePL), `CurrentButton); CloseDialog(); return(ret); } }; }); /*--------------------------------------------------------------------- * Make a proposal for a Mountpoint *--------------------------------------------------------------------- */ define GetMountPointProposal( map targetMap ) ``{ list base = [ "/", "/usr", "/boot", "/var", "/opt", "/home" ]; list free_list = filter( `point, base, ``{ boolean found = false; foreach( `dev, `disk, targetMap, ``{ map|void parti = find( `part, lookup( disk, "partitions"), ``( lookup( part, "mount", "") == point && lookup( part, "delete", false) == false )); if ( parti != nil ) found = true; }); if (found) return( false ); return( true ); }); _debug( free_list ); if ( size( free_list ) == 0 ) { return( "/work" ); } else { return( select( free_list, 0 )); } }; /*--------------------------------------------------------------------- * Make a output string for "you can not create a partition, because: " *--------------------------------------------------------------------- */ define FormatCauseLine( symbol cause ) ``{ if ( cause == `no_ext ) return( UI(_("No extended partition exists.") )); if ( cause == `dev_full ) return( UI(_("There exists already four primary/extended partitions.") )); if ( cause == `no_extsp ) return( UI(_("No space left in the extended partition.") )); if ( cause == `to_many ) return( UI(_("Too many logical drives already exist .") )); if ( cause == `no_space ) return( UI(_("No space remaining") )); if ( cause == `already ) return( UI(_("An extended partition already exists"))); return( "---" ); }; /*--------------------------------------------------------------------- * Make a output string for "you can not create a partition, because: " *--------------------------------------------------------------------- */ define FormatYouCannotCause( boolean primary_is_possible, boolean extended_is_possible, boolean logical_is_possible, symbol no_primary_cause, symbol no_extended_cause, symbol no_logical_cause ) ``{ string pri_line = ""; string ext_line = ""; string log_line = ""; if ( primary_is_possible ) pri_line = UI(_("Primary partition creation: Is possible\n")); // example "No primary partition: No space left else pri_line = UI(_("No primary partition: ")) + FormatCauseLine( no_primary_cause ) + "\n"; if ( logical_is_possible ) log_line = UI(_("Logical partition creation: Is possible\n")); // example "No logical partition: No space left else log_line = UI(_("No logical- partition: ")) + FormatCauseLine( no_logical_cause ) +"\n" ; if ( extended_is_possible ) ext_line = UI(_("Extendend partition creation: Is possible\n")); // example "No extended partition: No space left else ext_line = UI(_("No extended partition: ")) + FormatCauseLine( no_extended_cause ) +"\n"; return ( pri_line + ext_line + log_line ); }; /*--------------------------------------------------------------------- * Checks the generated partion table. (adds whole_disk - flags to the table) *--------------------------------------------------------------------- * Checkpoints: * - popup if unformated mounted partitions exist * - checks if yast can take a whole disk * all partitions have a fsid have of the type 130 131 5 // all fsid 131 partitions are mounted * * todo: move the following test to this function * - checks if / mountpoint is set * - check if the boot partition ends in < 1024 cylinder (/or/boot) * - checks thart the boot partition is not a reiserfs (/or/boot) * - check that all reiser Filesystems are bigger than 60MB */ define check_created_partiton_table( map targetMap ) ``{ boolean partition_mounted_but_not_formated = false; boolean have_swap = false; foreach( `disk, `diskinfo, targetMap, ``{ list part_info = lookup( diskinfo, "partitions" ); boolean whole_disk = true; foreach( `part, part_info, ``{ if ( lookup( part, "delete", false) == false ) { // All valid partitions ... integer fsid = lookup( part, "fsid", 0); boolean is_mounted = (lookup( part, "mount", "") != ""); if ( (lookup( part, "mount", "" ) == "swap" ) && (fsid == 130) ) { have_swap = true; } // | NOT // v if ( ! (( (fsid == 130) || (fsid == 5) ) && ((fsid == 131) && is_mounted) ) ) { whole_disk = false; } if ( fsid == 131 && lookup( part, "mount", nil ) != nil && substring( lookup( part, "mount"), 0, 1 ) == "/" && lookup( part, "format", false ) == false ) { partition_mounted_but_not_formated = true; } } }); diskinfo = add( diskinfo, "whole_disk", whole_disk ); targetMap = add( targetMap, disk, diskinfo ); } ); if ( !have_swap ) { UI(`DisplayMessage( _("\ You have not created and activated a swap partition. There is nothing wrong with that, but in common it is highly recommended to create an activate a swap partition. Created swap partitions are listed in the main window with the type \"Linux Swap\". An activated swap partition have a mountpoint \"swap\"")) ); } if ( partition_mounted_but_not_formated ) { UI(`DisplayMessage(_("\ You have a mounted partition, which will not be formatted. There is nothing wrong with that, but notice that YaST2 is now not able to determine the free space exactly. YaST2 treats this partitions like an empty partitions, because it does not know how many space will be overwritten. So be sure, not to install to much packages."))); } return( targetMap ); }; /*--------------------------------------------------------------------- * At the moment with a pdisk-formated disk you cannot * create partitions *------------------------------------ * in: current disk, `warn_nor | `warn_delete | `warn_create * out true | false *--------------------------------------------------------------------- */ define check_pdisk( map curr_disk, symbol warn ) ``{ if (filter (`pentry, lookup( curr_disk, "partitions", []), ``(lookup (pentry, "type", `empty) == `pdisk)) != [] ) { // This disk has an non-fdisk partition scheme // only mount-point if ( warn == `warn_delete ) { UI (`DisplayMessage (_("\ Caution: This disk has pdisk partitions There is nothing wrong with that, but at the moment YaST2 cannot delete those partitions. It can only mount pdisk partitions. To delete pdisk partitions, switch to a virtual console and delete those partitions manually."))); } else if ( warn == `warn_create ) { UI (`DisplayMessage (_("\ Caution: This disk has pdisk partitions There is nothing wrong with that, but at the moment YaST2 cannot create those partitions. It can only mount pdisk partitions. To create new pdisk partitions, switch to a virtual console and create those partitions manually. The other way is to use an empty disk, without any partitions. Then YaST2 can also create and delete partitions."))); } else if ( warn == `warn_create ) { // dont warn } return true; } else { return false; } }; ///////////////////////////////////////////////////////////////////////////////////////////////////// // MAIN: ///////////////////////////////////////////////////////////////////////////////////////////////////// // boolean test_mode = true; boolean test_mode = false; map targetMap = $[]; any ret = nil; map testtargetMap = $[ "/dev/sda":$[ "bus":"SCSI", "name":"1. SCSI, 8.54 GB, /dev/sda, IBM-DNES-309170W", "cyl_count":1114, "cyl_size":8224768, "vendor":"", "model": "DNES-309170-X", "partitions":[ $["delete":false, "fsid":130, "fstype":"Linux swap", "mount":"swap", "nr":4, "ori_nr":4, "region":[280, 129], "type":`primary], $["delete":true, "fsid":130, "fstype":"Linux swap", "mount":"swap", "nr":4, "ori_nr":4, "region":[194, 65], "type":`logical], $["fsid":11, "fstype":"Windows", "nr":1, "region":[1, 254], "type":`primary], $["fsid":130, "fstype":"Linux swap", "nr":2, "region":[255, 16], "type":`primary], $["fsid":130, "fstype":"Linux swap", "nr":2, "region":[255, 16], "type":`pdisk], $["delete":true, "fsid":131, "fstype":"Linux native", "nr":2, "region":[271, 844], "type":`primary] ] ], "/dev/sdb":$[ "bus":"SCSI", "name":"1. SCSI, 8.54 GB, /dev/sda, IBM-DNES-309170W", "cyl_count":11141, "cyl_size":8224768, "vendor":"IBM DNES-309170-XEW", "partitions":[ $["fsid":131, "fstype":"Linux native", "nr":1, "format":true, "region":[1, 254], "type":`primary], $["fsid":5, "fstype":"Extended", "nr":4, "region":[272, 1000], "type":`extended], $["fsid":11, "fstype":"Windows", "nr":2, "region":[255, 16], "type":`primary], $["fsid":130, "fstype":"Linux swap", "nr":5, "region":[272, 100], "type":`logical], $["fsid":130, "fstype":"Linux", "nr":6, "region":[372, 100], "type":`logical], $["fsid":131, "fstype":"Linux", "nr":7, "region":[472, 300], "type":`logical], $["fsid":131, "fstype":"Linux native", "nr":3, "region":[1273, 9869], "type":`primary] ]]]; if (!test_mode) { targetMap = lookup ( user_settings, "targets", $[] ); } else { targetMap = testtargetMap; _debug( "TTTTTTT-TESTMODE ___________________-", targetMap ); _debug( "TTTTTTT-TESTMODE ___________________-", targetMap ); _debug( "TTTTTTT-TESTMODE ___________________-", targetMap ); _debug( "TTTTTTT-TESTMODE ___________________-", targetMap ); } targetMap = InitTargets( targetMap ); list table_list = []; if (test_mode) { table_list = FillPartitionList( targetMap ); // table_list = [ // `item(`id(1), "/dev/hda", "1", "1115", "8.5 GB", " ", "Seagate ST 48012", " "), // `item(`id(2), "/dev/hda1", "1", "65", "509.8 MB", " ", "FAT16", " "), // `item(`id(3), "/dev/hda2", "66", "150", "666.7 MB", " ", "NTFS", " "), // `item(`id(4), "/dev/hda3", "301","1024", "5.5 GB", " ", "Extended", " "), // `item(`id(5), "/dev/hda5", "301","302", "7.8 MB", "F", "Linux ", "/boot") // ]; } else { table_list = FillPartitionList( targetMap ); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// MAIN DIALOG term contents = `VBox(`Label(""), // for the translators: the spaces in the column descriptions are needed for the correct column width example " Size " `Table(`id(`table),`header(_("Device"), // Column header: minimum = 5 characters fill with space if needed `Right(_("Start")), // Column header: minimum = 4 characters fill with space if needed `Right(_("End ")), // Column header: centered / minimum = 11 characters / fill with space if needed `Right(_(" Size ")), // Column header: centered / minimum = 3 characters / fill with space if needed `Right(_(" F ")), // Column header _("Type"), // Column header: centered / minimum = 7 characters / fill with space if needed _(" Mount ")), table_list ), // main dialog: Button Create partition `HBox( `PushButton(`id(`create), _("&Create") ), // main dialog: Button Delete partition `PushButton(`id(`delete), _("&Delete") ), // main dialog: Button Edit partition `PushButton(`id(`edit), _("&Edit") ), // main dialog: Button Reset current changes and then read partition table `PushButton(`id(`reread), _("&Reset and Re-Read") ) ) ) ; string help_text = ""; // helptext expert partitioning. 1 of 16 help_text = UI(_("<p> Partition your hard disk(s).. </p>")); // helptext expert partitioning. 2 of 16 help_text = help_text + UI(_("<p> This is intended for <b>experts</b>. If you are not familiar with the concepts of hard disk <b>partitions</b> and how to use them, you might want to go back and select <b>automatic</b> partitioning. </p>")); // helptext expert partitioning. 3 of 16 help_text = help_text + UI(_("<p> Please note that <b>nothing will be written to your hard disk</b> until you confirm the entire installation in the last installation dialog. Until that point, you can safely abort the installation. </p>")); // helptext expert partitioning. 4 of 16 help_text = help_text + UI(_("<p> The table to the right shows the current partitions of all of your hard disks. </p>")); // helptext expert partitioning. 5 of 16 help_text = help_text + UI(_("<p><b>Hard disks</b> are designated like this </p> <tt>/dev/hda </tt>1st EIDE disk <tt>/dev/hdb </tt>2nd EIDE disk <tt>/dev/hdc </tt>3rd EIDE disk <p>etc.</p> <p>- or - </p> <tt>/dev/sda </tt>1st SCSI disk <tt>/dev/sdb </tt>2nd SCSI disk <tt>/dev/sdc </tt>3rd SCSI disk")); // helptext expert partitioning. 6 of 16 help_text = help_text + UI(_("<p>etc.</p> <p> This notation always refers to the entire disk. </p>")); // helptext expert partitioning. 7 of 16 help_text = help_text + UI(_("<p> <b>Partitions</b> are designated like this: </p>")); // helptext expert partitioning. 8 of 16 help_text = help_text + UI(_("<p><tt>/dev/hda1 </tt>1st primary partition on the 1st EIDE disk.</p> <p><tt>/dev/hda2 </tt>2nd primary partition on the 1st EIDE disk.</p> <p>...</p> <p><tt>/dev/hda5 </tt>1st logical partition within the extended partition on the first EIDE disk. <b>Note:</b> this is always #5, even if there are less than four primary partitions.</p>")); // helptext expert partitioning. 9 of 16 help_text = help_text + UI(_("<p><tt>/dev/hda6 </tt>2nd logical partition</p> <p>...</p> <p><tt>/dev/sda1 </tt>etc. accordingly for SCSI.</p>")); // helptext expert partitioning. 10 of 16 help_text = help_text + UI(_("<p> On the i386 platform (i.e. normal PCs), there can be no more than four <b>primary partitions</b> on any hard disk (since the respective table in the master boot record can hold no more than four entries). </p>")); // helptext expert partitioning. 11 of 16 help_text = help_text + UI(_("<p> Please note that most PCs have a <b>BIOS</b> limitation that restricts bootable partitions to cylinders <b>1024</b> and below. </p>")); // helptext expert partitioning. 12 of 16 help_text = help_text + UI(_("<p> In order to be able to boot from a partition, make sure it ends below this cylinder 1024 boundary. Create a separate partition and mount it as <b>/boot</b>, if necessary. A partition consisting of one single cylinder (at least 2 MB) is usually sufficient for that. </p>")); // helptext expert partitioning. 13 of 16 help_text = help_text + UI(_("<p> One of the four primary partitions may be an <b>extended partition</b>. This extended partition can contain one or more <b>logical partitions</b>. </p>")); // helptext expert partitioning. 14 of 16 help_text = help_text + UI(_("<p> The extended partition itself cannot hold any data. In order to use it, you must create logical partitions within it. Those logical partitions may contain any kind of Linux partition (Linux file systems or Linux swap partition) as well as partitions for other operating systems. </p>")); // helptext expert partitioning. 15 of 16 help_text = help_text + UI(_("<p> In connection with advanced boot managers such as <b>LILO</b>, you can even boot your computer from a logical partition. </p>")); // helptext expert partitioning. 16 of 16 help_text = help_text + UI(_("<p> Please note that the extended partition will <b>overlap</b> with the logical partitions: For an extended partition from cylinder 200 to 500, logical partitions could range from (say) 200 to 250, 251 to 400 and 401 to 500. </p>")); help_text = help_text + "<p>-----------<\p><\p>V.44<\p>"; // Main dialog: Header UI(`SetWizardContents(_("Expert Partitioner"), contents, help_text, Args(0), Args(1))); string spaces = " "; string spaces2 = " "; string spaces3 = " "; string spaces4 = " "; string spaces5 = " "; string spaces6 = " "; string spaces7 = " "; string spaces8 = " "; string spaces9 = " "; string spaces10 = " "; string spaces11 = " "; string spaces12 = " "; string spaces13 = ""; /////////////////////////////////////////////////////////////////////////////////////////////////////////// //// Loop for User Input .... /////////////////////////////////////////////////////////////////////////////////////////////////////////// repeat { table_list = FillPartitionList( targetMap ); UI( `ChangeWidget(`id(`table), `Items, table_list)); ret= UI(`UserInput()); //////////////////////////////////////////////////////////////////////////////////////////////////////// //// CREATE //////////////////////////////////////////////////////////////////////////////////////////////////////// if (ret == `create) { any curr_diskdev = UI(`ChooseDisk( targetMap )); symbol create_type = `none; map curr_disk = lookup(targetMap, curr_diskdev); boolean pdisk_disk = false; /////////////////////////////////////////////////////// // At the moment with a pdisk-formated disk you cannot // create partitions: check it ... if (curr_diskdev != nil) // check cancel-button { pdisk_disk = check_pdisk( curr_disk, `warn_create ); } /////////////////////////////////////////////////////// // If we have a no pdisk-disk and we have a current disk // lets start .... if (curr_diskdev != nil && !pdisk_disk ) { list possibilities = CheckCreatePossibilities( curr_diskdev, curr_disk ); boolean primary_is_possible = select( possibilities, 0); boolean extended_is_possible = select( possibilities, 1); boolean logical_is_possible = select( possibilities, 2); symbol no_primary_cause = select( possibilities, 3); symbol no_extended_cause = select( possibilities, 4); symbol no_logical_cause = select( possibilities, 5); list|void log_slot = []; list|void p_e_slot = []; ////////////////////////////////////////////////////////// // Test if there is space left on the device log_slot = GetLogicalSlot(curr_diskdev, curr_disk); p_e_slot = GetSlot(curr_diskdev, curr_disk); if (log_slot == nil && logical_is_possible ) no_logical_cause = `no_space; if (p_e_slot == nil && primary_is_possible ) no_primary_cause = `no_space; if (p_e_slot == nil && extended_is_possible) no_extended_cause = `no_space; if (log_slot == nil) logical_is_possible = false; if (p_e_slot == nil) primary_is_possible = false; if (p_e_slot == nil) extended_is_possible = false; /*---------------------------------------------------------------------- * At the same time is not possible, that both "logial_part_is_possible" * and "extended_part_is_possible" are true * so we have 6 possible situations * * to show this we use * "P" for primary_part_is_possible * "E" for extended_part_is_possible * "L" for logial_part_is_possible * * "p" for primary_part_is_possible == false * "e" for extended_part_is_possible == false * "l" for logial_part_is_possible == false * * * PE : I can create a primary or exended part. * PL : Extended part. exist. I can create a primary or a logical * Pel : only a priary is possible, when the extended part. has no space left * * pE : Not possible, if "E" is possible always "P" is possible too. * pL : only a logical is possible, if together 4 primary and extended * partitions are already created * pel : no partitions are possible *--------------------------------------------------------------------------*/ if ( !primary_is_possible && !extended_is_possible && !logical_is_possible ) { // ------pel-------- string text = sformat( UI(_("It is not possible, to create a partition on %1\n\n%2")), curr_diskdev, FormatYouCannotCause( primary_is_possible, extended_is_possible, logical_is_possible, no_primary_cause, no_extended_cause, no_logical_cause )); UI(`DisplayMessage(text)); } else if ( !primary_is_possible && logical_is_possible ) { //------pL---------- create_type = `logical; } else if ( !primary_is_possible && extended_is_possible ) { //------pE---------- create_type = `extended; } else if ( primary_is_possible && !extended_is_possible && !logical_is_possible ) { //------Pel---------- create_type = `primary; } else if ( primary_is_possible && extended_is_possible ) { //------PE---------- create_type = UI(`ChoosePart("PE")); // curr_diskdev } else if ( primary_is_possible && logical_is_possible ) { //------PL---------- create_type = UI(`ChoosePart("PL")); // popup } else { y2log( .error, "Error partition check" ); create_type = UI(`ChoosePart("PEL")); // popup _debug( possibilities ); } if ( create_type != `none ) { list partitions = lookup( curr_disk, "partitions"); integer curr_nr = 0; list base = []; list slot = []; // search for the first possible dev nr if ( create_type == `primary || create_type == `extended || create_type == `logical ) { if ( create_type == `primary || create_type == `extended) { base = [1,2,3,4]; slot = p_e_slot; } else // logical { base = [5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39, 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64]; slot = log_slot; } //---------------------------------------------------------- // dev_nb List of numbers of extende an primary partitions // result: list of all free primaty|extended partition numbers list dev_nb = maplist( `part, filter( `pa, partitions, ``(lookup( pa, "delete", false) == false)), ``(lookup( part, "nr") )); list result = filter( `base_nr, base, ``( find(`nr, dev_nb, ``(nr == base_nr)) == nil)); curr_nr = select( sort( result ), 0 ); } //--------------------------------------------------------------------------------------- // Present the Create-Popups ... //--------------------------------------------------------------------------------------- string titleC = ""; // Popup Create Partition: Description of partition %1 and %3 are many spaces, %2 is for example "/dev/hda3" if ( create_type == `primary ) titleC = sformat( UI(_("%1 Create a primary partition on %2 %3")), spaces, curr_diskdev, spaces ); // Popup Create Partition: Description of partition %1 and %3 are many spaces, %2 is for example "/dev/hda3" if ( create_type == `extended ) titleC = sformat( UI(_("%1 Create a extended partition on %2 %3")), spaces11, curr_diskdev, spaces11 ); // Popup Create Partition: Description of partition %1 and %3 are many spaces, %2 is for example "/dev/hda3" if ( create_type == `logical ) titleC = sformat( UI(_("%1 Create a logical partition on %2 %3")), spaces, curr_diskdev, spaces ); map|void new_val = nil; string start_cyl_str = sformat( "%1", select( slot, 0)); string end_cyl_str = sformat( "%1", select( slot, 1)); if ( create_type == `extended ) { new_val = UI(`CreateEditExtendedPartDlg(titleC, true, 5, start_cyl_str, end_cyl_str, "", create_type, curr_diskdev, curr_disk, lookup( curr_disk, "cyl_size", 1000000), false )); } else { new_val = UI(`EditOrCreatePartDlg(titleC, true, 131, start_cyl_str, end_cyl_str, GetMountPointProposal(targetMap), create_type, curr_diskdev, curr_disk, lookup( curr_disk, "cyl_size", 1000000), `ext2, targetMap )); } if ( new_val != nil ) { // $["fsid":131, "fstype":"Linux native", "nr":1, "region":[0, 255], "type":`primary], map new_part = $[]; new_part = add( new_part, "create", true ); new_part = add( new_part, "nr", curr_nr ); new_part = add( new_part, "type", create_type ); new_part = add( new_part, "fsid", lookup( new_val, "fsid") ); new_part = add( new_part, "format", lookup( new_val, "format") ); new_part = add( new_part, "mount", lookup( new_val, "mount") ); new_part = add( new_part, "used_fs", lookup( new_val, "used_fs", `unknown)); list region = add( [], tointeger( lookup( new_val, "start_cyl"))); region = add( region, UI(`ToEndRegion( lookup( new_val, "start_cyl"), lookup( new_val, "end_part"), lookup( curr_disk, "cyl_size", 1000000)))); new_part = add( new_part, "region", region ); partitions = add( partitions, new_part ); curr_disk = add( curr_disk, "partitions", partitions ); targetMap = add( targetMap, curr_diskdev, curr_disk ); } } } } //////////////////////////////////////////////////////////////////////////////////////////////////////// //// EDIT //////////////////////////////////////////////////////////////////////////////////////////////////////// if (ret == `edit) { any w_id = UI( `QueryWidget(`id(`table), `CurrentItem) ); // notify a line is selected if ( w_id != nil ) { string id = UI( `QueryWidget(`id(`table), `CurrentItem) ); // the user is not allowed to select a disk, he must select a partition if ( substring( id, 2, 1) != "." ) { // %1 is a disk device, example: You have selected the disk /dev/hda, but can only edit a partition like /dev/hda11, /dev/hda2, UI(`DisplayMessage(sformat(UI(_("\n You have selected the disk %1, but can \n only edit a partition like %11, %12, ... \n")), id ))); } else { // parse "id" of the seklected line: string dev = substring( id, 3 ); integer number = tointeger( substring( id , 0, 2)); // read the data of the selected partition from the db (user_settings.targets) string devStr = sformat("%1%2", dev, number ); map curr_disk = lookup( targetMap, dev ); // check if it is a pdisk disk, then editing is restricted boolean pdisk_disk = check_pdisk( curr_disk, `warn_not ); map curr_part = find ( `c_part, lookup( curr_disk, "partitions"), ``(lookup(c_part, "nr")==number && (lookup(c_part, "delete", false) == false) )); list partitions_without_current = filter( `c_part, lookup( curr_disk, "partitions"), ``(!(lookup(c_part, "nr")==number && (lookup(c_part, "delete", false) == false) ))); map disk_without_current = add( curr_disk, "partitions", partitions_without_current); map target_without_current = add( targetMap, dev, disk_without_current ); string start_cyl = sformat( "%1", select(lookup(curr_part, "region"), 0)); string end_cyl = sformat( "%1", select(lookup(curr_part, "region"), 0) + select(lookup(curr_part, "region"), 1) -1 ); boolean input_is_ok = false; integer fs = 130; boolean format = false; string mount_point = ""; string erg_start_cyl = ""; string end_part = ""; map | void new_val = $[]; // new values as map ////////////////////////////////////// // There are three different Editors: // - "normal" // - extended // - already existing if ( IsExtended( lookup(curr_part, "fsid") )) { if ( lookup(curr_part, "create", false) == true ) { //////////////////////////////////////////////////////////////// // header of the Dialog Create a partition (Please don t use // a shorter translation, In doubt fill with Blanks left and right) string title = UI(spaces10)+UI(_("Edit an extended partition "))+ UI(devStr)+ UI(spaces10); new_val = UI(`CreateEditExtendedPartDlg( title, lookup(curr_part, "format", false), lookup(curr_part, "fsid", 130), start_cyl, end_cyl, lookup(curr_part, "mount", ""), lookup(curr_part, "type"), devStr, disk_without_current, lookup( curr_disk, "cyl_size", 1000000), true )); } else { UI(`DisplayMessage( _("An already existing extended partition cannot be changed! You must delete this partition and then create a new one with the new parameters. All data in this partition will be LOST!" ))); new_val = nil; } } else if ( !lookup(curr_part, "create", false) ) { /////////////////////////////////////////////////////////////////////////////////////// // header of the Dialog Create a partition (Please don t use a shorter // translation, In doubt fill with Blanks left and right) string title = UI(spaces8)+UI(_("Edit an already existing partition "))+ UI(devStr)+ UI(spaces8); new_val = UI(`ExistingPartitionDlg(title, lookup(curr_part, "format", false), lookup(curr_part, "fsid", 130), start_cyl, end_cyl, lookup(curr_part, "mount", ""), disk_without_current, target_without_current, lookup( curr_part, "used_fs", `unknown), lookup( curr_disk, "cyl_size", 1000000), pdisk_disk )); } else { /////////////////////////////////////////////////////////////////////////////////////// // header of the Dialog Create a partition (Please don t use a // shorter translation, In doubt fill with Blanks left and right) string title = UI(spaces2)+UI(_("Edit a partition"))+ UI(devStr)+ UI(spaces2); new_val = UI(`EditOrCreatePartDlg(title, lookup(curr_part, "format", false),lookup(curr_part, "fsid", 130), start_cyl, end_cyl, lookup(curr_part, "mount", ""), lookup(curr_part, "type"), devStr, disk_without_current, lookup( curr_disk, "cyl_size", 1000000), lookup( curr_part, "used_fs", `unknown), target_without_current )); } if ( new_val != nil ) // not canceld { curr_part = add( curr_part, "fsid", lookup( new_val, "fsid") ); curr_part = add( curr_part, "format", lookup( new_val, "format") ); curr_part = add( curr_part, "mount", lookup( new_val, "mount") ); curr_part = add( curr_part, "used_fs", lookup( new_val, "used_fs", `unknown)); list region = add( [], tointeger( lookup( new_val, "start_cyl"))); region = add( region, UI(`ToEndRegion( lookup( new_val, "start_cyl"), lookup( new_val, "end_part"), lookup( curr_disk, "cyl_size", 1000000)))); curr_part = add( curr_part, "region", region ); list r_part = filter( `c_part, lookup( curr_disk, "partitions"), ``(lookup(c_part, "nr")!=number || (lookup(c_part, "delete", false) == true))); r_part = add( r_part, curr_part ); curr_disk = add( curr_disk, "partitions", r_part ); targetMap = add( targetMap, dev, curr_disk ); } } } else { // No line is selcted: UI(`DisplayMessage(_("To edit a partition, you have to select one in main dialog") )); } } //////////////////////////////////////////////////////////////////////////////////////////////////// // DELETE //////////////////////////////////////////////////////////////////////////////////////////////////// if (ret == `delete) { string id = UI( `QueryWidget(`id(`table), `CurrentItem) ); // the user is not allowed to select a disk, he must select a partition if ( substring( id, 2, 1) != "." ) { UI(`DisplayMessage(sformat(UI(_("\n You have selected the disk %1, but can \n only delete a partition like %11, %12, ... \n")), id ))); } else { ////////////////////////////////////////////////////////////////////////////// // delete algorithm: // if you find newly created (but until now not realy written) partition // (sign: "create = true"): delete it // else there must be already existing partition: mark it with "delete = true" // string dev = substring( id, 3 ); integer number = tointeger( substring( id , 0, 2)); map curr_disk = lookup( targetMap, dev ); /////////////////////////////////////////////////////// // At the moment with a pdisk-formated disk you cannot // create/delete partitions: check it ... boolean pdisk_disk = check_pdisk( curr_disk, `warn_delete ); if ( !pdisk_disk ) { list curr_partitions = lookup( curr_disk, "partitions"); map curr_part = find( `parti, curr_partitions, ``( (lookup(parti,"nr") == number) && (lookup( parti,"delete",false) == false))); if ( fdisk_type == `intel ) { // if it is an extended partition -> delete all logical! // ----------- // remove all partition with a "nr" >= 5 i.e. all logical // we dont need to mark already existing part. with delete, // because fdisk deletes the logical automaticly // also, when a deleted extended is newly created cause the delete operation // is done! if ( lookup( curr_part, "type") == `extended ) { curr_partitions = filter( `parti, curr_partitions, ``(lookup(parti,"nr")< 5)); } } map|void part_created = find( `parti, curr_partitions, ``( (lookup(parti,"nr") == number) && (lookup( parti,"create",false ) == true))); if ( part_created == nil ) { // No newly created found... // Mark already existant with "delete" curr_partitions = maplist( `parti, curr_partitions, ``( { if ( lookup( parti, "nr" ) == number ) { return( add( add( parti, "delete", true ), "nr", lookup( parti, "ori_nr") )); } else { return( parti ); } })); } else { // delete newly created partition curr_partitions = filter( `parti, curr_partitions, ``( ! ((lookup( parti, "nr" ) == number) && (lookup( parti, "create", false ) == true)) )); } /////////////////////////////////////////////// // If you delete a logical partition you must decrease the number of every logical partition, // that has a higher number than the deleted // start: sda1 sda2 sda5 sda6 sda7 sda8 sda9 sda10 // delete sda7 // you must sda8 -> sda7 sda9 -> sda8 sda10 -> sda9 // end with: sda1 sda2 sda5 sda6 sda7 sda8 sda9 if ( lookup( curr_part, "type" ) == `logical ) { curr_partitions = maplist( `parti, curr_partitions , ``( { // only the valid ones if ( (lookup( parti,"delete",false) == false) && (lookup( parti, "nr") > number) ) { return( add( parti, "nr", lookup( parti, "nr")-1 )); } else { return( parti ); } })); } curr_disk = add( curr_disk, "partitions", curr_partitions ); targetMap = add( targetMap, dev, curr_disk ); } } //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// } //////////////////////////////////////////////////////////////////////////////////////////////////// // REREAD //////////////////////////////////////////////////////////////////////////////////////////////////// if (ret == `reread) { any ret2 = UI(`YesOrNo(_("Do you really want to reread the partiton table?\nAll current changes will be lost!"), _("&Yes"), _("&No") ) ); if (ret2 == true) { foreach( `dev, `disk, targetMap, ``{ _debug( "reread dev", dev); path diskpath = topath ("." + substring (dev, 5)); list partitions = check4partitions (diskpath, architecture); disk = add (disk, "partitions", partitions); // add constructed target map to list of all targets targetMap = add (targetMap, dev, disk); targetMap = InitTargets( targetMap ); }); } } //////////////////////////////////////////////////////////////////////////////////////////////////// // End of Actions, Now check the returncode //////////////////////////////////////////////////////////////////////////////////////////////////// if (ret == `next || ret == `back) { _debug ("WHOLLLLLLE", targetMap ); if ( ret == `next ) { targetMap = check_created_partiton_table( targetMap ); _debug ("WHOLLLLLLE", targetMap ); } // write partition information user_settings = add(user_settings, "targets", targetMap ); // force re-evaluation of lilo settings in inst_lilo_info later user_settings = add (user_settings, "lilo", "" ); user_settings = add (user_settings, "lilo_device", "" ); if ( ret != `back ) { if (ret == `apply) return `again; // checking targetMap if (ret == `next) { boolean swap_found = false; boolean boot_found = false; boolean root_found = false; integer boot_end = 0; integer root_end = 0; symbol root_fs = `unknown; symbol boot_fs = `unknown; list avail_part = get_partition_info( targetMap, false ); foreach ( `part, avail_part, ``{ if ( lookup( part, "name" ) == "/" ) { root_found = true; root_end = select(lookup( part, "region"), 0) + select(lookup( part, "region"), 1) -1; root_fs = lookup( part, "used_fs", `unknown ); } else if ( lookup( part, "name" ) == "/boot" ) { boot_found = true; boot_end = select(lookup( part, "region"), 0) + select(lookup( part, "region"), 1) -1; boot_fs = lookup( part, "used_fs", `unknown ); } } ); if ( !root_found ) { UI(`DisplayMessage(_("\ YaST2 needs at least one partition to install SuSE Linux:\n\ the root \"/\" partition.\n\ Please create the requested mountpoint." ))); return `again; } if ( boot_found ) { if ( boot_end >= 1024 ) { any ret = UI(`YesOrNo(_("\ Warning: With the current selection your SuSE Linux installation will not be directly bootable. Your boot partition has a end cylinder over 1024. \nDo you want to change this?"), _("&Yes"), _("&No") ) ); if (ret == true) return `again; return `next; } if ( boot_fs == `reiser ) { UI(`DisplayMessage(_("\ In the current version, LILO cannot per default boot a boot-partition with Reiser Filesystem. Please choose Ext2 as the filesystem for the with /boot mounted partition" ))); return `again; } } else { if ( root_fs == `reiser ) { UI(`DisplayMessage(_("\ In the current version, LILO cannot per default boot partition with ReiserFS. Please choose Ext2 as the filesystem for your root partition or create a small boot-partition (10MB) with Ext2, and mount it as /boot" ))); return `again; } // no boot but root if ( root_end >= 1024 ) { any ret = UI(`YesOrNo(_("\ Warning: With the current selection your SuSE Linux installation will not be directly bootable. Your boot partition root has a end cylinder over 1024. \nDo you want to change this?"), _("&Yes"), _("&No") ) ); if (ret == true) return `again; return `next; } } } } if ( ret != `back ) { if (ret == `apply) return `again; } } } until (ret == `next || ret == `back || ret == `cancel); return ret; }