home *** CD-ROM | disk | FTP | other *** search
Text File | 2006-11-29 | 63.4 KB | 1,573 lines |
- /*
-
-
- $Id: autopart.ycp 33409 2006-10-13 14:22:46Z ug $
- */
- {
- textdomain "autoinst";
-
- import "FileSystems";
-
- include "partitioning/partition_defines.ycp";
-
-
-
- map get_gap_info( map disk, map pd, boolean add_exist_linux );
- map add_cylinder_info( map conf, map gap );
- map get_perfect_list( list ps, map g );
- map process_partition_data( string dev, map solution );
- map find_matching_disk( list<string> disks, map target, map conf );
- map try_resize_windows( map disk );
- map remove_possible_partitions( map disk, map conf );
- map distribute_space( integer rest, list weights, list added, list ps );
- void add_part_recursive( list ps, map g );
- map normalize_gaps( list ps, map g );
- integer do_weighting( list ps, map g );
-
- symbol cur_mode = `free;
- integer cur_weight = -10000;
- map cur_gap = $[];
-
-
- list GetNoneLinuxPartitions(string device) {
- list ret = [];
- foreach ( string dev, map disk, Storage::GetTargetMap(), ``{
- if( Storage::IsRealDisk( disk ) && dev == device)
- {
- list<map> l = (list<map>) filter( map p, disk["partitions"]:[],
- ``(!p["delete"]:false &&
- !p["format"]:false &&
- !Partitions::IsLinuxPartition(p["fsid"]:0)) );
-
- l = filter(map p, l, ``(!contains( [`xfs, `ext2, `ext3, `jfs, `reiser],
- p["used_fs"]:`unknown)));
- l = filter(map p, l,
- ``(!FileSystems::IsSystemMp( p["mount"]:"", false )));
- if( size(l)>0 )
- {
- list<integer> ln = maplist( map p, l, ``(p["nr"]:0));
- ret = union( ret, ln );
- }
- }
- });
- y2milestone( "GetNoneLinuxPartitions ret=%1", ret );
- return( ret );
- }
-
-
- list<integer> GetAllPartitions(string device) {
- list<integer> ret = [];
- foreach ( string dev, map disk, Storage::GetTargetMap(), ``{
- if( Storage::IsRealDisk( disk ) && dev == device)
- {
- list<integer> l = maplist( map p, disk["partitions"]:[],
- ``(p["nr"]:0));
-
- ret = (list<integer>)union( ret, l );
- }
- });
- y2milestone( "All Partitions ret=%1", ret );
- return( ret );
- }
-
- /**
- * Read partition data from XML control file
- * @return map flexible propsal map
- */
- define list<map> preprocess_partition_config(list<map> xmlflex) {
-
- y2debug("xml input: %1", xmlflex );
- map<string,any> tm = Storage::GetTargetMap();
- list<map>partitioning = maplist(map d, xmlflex, ``{
-
- foreach( string key, [ "keep_partition_id", "keep_partition_num"], ``{
- list num = [];
- list<string> nlist = splitstring(d[key]:"", ",");
- foreach( string n, nlist, ``{ num = union( num, [tointeger(n)] );});
- d[key] = num;
- });
-
- list fsys = [];
- list<string> nlist = splitstring( d["keep_partition_fsys"]:"" , "," );
- foreach( string n, nlist,
- ``{
- symbol fs = FileSystems::FsToSymbol(n);
- if( fs != `none )
- {
- fsys = union( fsys, [ fs ] );
- }
- });
- d["keep_partition_fsys"] = fsys;
-
-
- list<map> user_partitions = d["partitions"]:[];
- if (size(user_partitions) == 0)
- {
- y2milestone("no partitions specified, creating default scheme");
- map root = $[];
- root["mount"] = "/";
- root["size"] = "max";
- map swap = $[];
- swap["mount"] = "swap";
- swap["size"] = "auto";
- user_partitions=add(user_partitions, swap);
- user_partitions=add(user_partitions, root);
-
- }
-
- list partitions = [];
- foreach(map partition, user_partitions,
- ``{
- if (haskey(partition, "maxsize"))
- {
- partition["max"] = kmgt_str_to_byte(partition["maxsize"]:"");
- }
-
- if (partition["size"]:"" != "")
- {
- string s = partition["size"]:"";
- if( tolower(s) == "auto" )
- {
- partition["size"] = -1;
- }
- else if( tolower(s) == "max" )
- {
- partition["size"] = 0;
- }
- else
- {
- partition["size"] = kmgt_str_to_byte( s );
- }
- }
-
- if( partition["size"]:0 == -1 && partition["mount"]:"" == "swap" )
- {
- partition["size"] = 1024*1024*Partitions::SwapSizeMb(0);
- }
-
- if( partition["mount"]:"" == Partitions::BootMount() )
- {
- if( partition["size"]:0 == -1 )
- partition["size"] = Partitions::MinimalNeededBootsize();
-
- if( partition["filesystem"]:`none == `none )
- partition["filesystem"] = Partitions::DefaultBootFs();
-
- if( partition["filesystem_id"]:0 == 0 )
- partition["filesystem_id"] = Partitions::FsidBoot();
-
- //partition["max_cyl"] = Partitions::BootCyl();
- }
-
- if( partition["size"]:0 == -1 )
- partition["size"] = 0;
-
- if (partition["used_by_type"]:`UB_NONE==`UB_LVM)
- partition["filesystem_id"] = Partitions::fsid_lvm;
- else if (partition["used_by_type"]:`UB_NONE==`UB_EVMS)
- partition["filesystem_id"] = Partitions::fsid_lvm;
- else if (partition["used_by_type"]:`UB_NONE==`UB_MD)
- partition["filesystem_id"] = Partitions::fsid_raid;
-
- partition["fsid"] = partition["filesystem_id"]:Partitions::fsid_native;
-
- y2debug("partition: %1", partition);
- partitions = add( partitions, partition );
- });
-
- if (d["type"]:`CT_UNKNONW!=`CT_LVM && d["type"]:`CT_UNKNONW!=`CT_EVMS) {
- d["partitions"] = partitions;
- }
- return (d);
- });
-
- y2milestone( "conf: %1", partitioning );
- return( partitioning );
- }
-
- define map try_add_boot( map conf, map disk ) {
- boolean boot =
- size(filter( map e, conf["partitions"]:[],
- ``(e["mount"]:""==Partitions::BootMount() || (e["partition_id"]:0 == Partitions::FsidBoot() && Partitions::FsidBoot() != 131 ) ))) > 0;
- boolean root = size(filter( map e, conf["partitions"]:[],
- ``(e["mount"]:""=="/"))) > 0;
- map tc = (map) eval(conf);
- if( !boot && root &&
- (disk["cyl_count"]:0 > Partitions::BootCyl() ||
- Arch::ia64 () || Arch::ppc () || Arch::sparc ()) )
- {
- map pb = $[];
- if( ! Arch::ppc () ) {
- pb["mount"] = Partitions::BootMount();
- pb["fsys"] = Partitions::DefaultBootFs();
- }
- pb["size"] = Partitions::MinimalNeededBootsize();
- pb["filesystem"] = Partitions::DefaultBootFs();
- pb["fsid"] = Partitions::FsidBoot(); // FIXME: might be useless
- pb["filesystem_id"] = Partitions::FsidBoot();
- pb["id"] = Partitions::FsidBoot(); // FIXME: might be useless
- pb["auto_added"] = true;
- pb["type"] = `primary; // FIXME: might be useless
- pb["partition_type"] = "primary";
- pb["nr"] = 1;
- //pb["max_cyl"] = Partitions::BootCyl();
- //tc["partitions"] = add( tc["partitions"]:[], pb );
- tc["partitions"] = merge( [ pb ], tc["partitions"]:[] );
- y2milestone( "boot added automagically pb %1", pb );
- }
- return( tc );
- }
-
-
- /**
- * Find matching disk
- */
- define map find_matching_disk( list<string> disks, map target, map conf )
- ``{
- map<string,map> solutions = $[];
-
- cur_weight = -100000;
- cur_gap = $[];
- foreach( string k, disks,
- ``{
- map e = target[k]:$[];
- map pd = conf;
- y2milestone( "processing disk %1", k );
- y2milestone( "parts %1", conf["partitions"]:[] );
- map tc = try_add_boot( conf, e );
- cur_mode = `free;
- if( !tc["prefer_remove"]:false )
- {
- map gap = get_gap_info( e, pd , false );
- tc = add_cylinder_info( tc, gap );
- map l = get_perfect_list( tc["partitions"]:[], gap );
- if( size(l)>0 )
- {
- solutions[k] = eval(l);
- solutions[k,"disk"] = eval(e);
- }
- cur_mode = `reuse;
- map egap = get_gap_info( e, pd, true );
- if( size(egap["gap"]:[]) > size(gap["gap"]:[]) )
- {
- tc = add_cylinder_info( tc, egap );
- l = get_perfect_list( tc["partitions"]:[], egap );
- if( size(l)>0 &&
- (!haskey(solutions,k) ||
- (haskey( l, "weight" ) &&
- l["weigth"]:0 > solutions[k,"weigth"]:0 )))
- {
- y2milestone( "solution reuse existing" );
- solutions[k] = eval(l);
- solutions[k,"disk"] = eval(e);
- }
- }
- cur_mode = `resize;
- map rw = try_resize_windows( e );
- if( size( filter( map p, rw["partitions"]:[],
- ``(haskey(p, "winfo")) ))>0 )
- {
- egap = get_gap_info( rw, pd, true );
- tc = add_cylinder_info( tc, egap );
- l = get_perfect_list( tc["partitions"]:[], egap );
- if( size(l)>0 &&
- (!haskey(solutions,k) ||
- (haskey( l, "weight" ) &&
- l["weigth"]:0 > solutions[k,"weigth"]:0 )))
- {
- y2milestone( "solution resizing windows" );
- solutions[k] = eval(l);
- solutions[k,"disk"] = eval(rw);
- }
- }
- }
- else
- {
- cur_mode = `free;
- map rp = remove_possible_partitions( e, tc );
- map gap = get_gap_info( rp, pd, false );
- tc = add_cylinder_info( tc, gap );
- map l = get_perfect_list( tc["partitions"]:[], gap );
- if( size(l)>0 )
- {
- solutions[k] = eval(l);
- solutions[k,"disk"] = eval(rp);
- }
- }
- });
- map ret = $[];
- if( size(solutions)>0 )
- {
- foreach( string k, map e, solutions,
- ``{
- y2milestone( "disk %1 weight %2", k, e["weight"]:0 );
- });
- list<string> disks = maplist( string k, map e, solutions, ``(k) );
- disks = sort( string a, string b, disks,
- ``(solutions[a,"weight"]:0>solutions[b,"weight"]:0));
- y2milestone( "sorted disks %1", disks );
- ret = solutions[disks[0]:""]:$[];
- ret["device"] = disks[0]:"";
- }
- return( ret );
- }
-
-
-
- /**
- * Process partition data
- */
- define map process_partition_data( string dev, map solution )
- ``{
- map disk = solution["disk"]:$[];
- list<map> partitions = [];
- string value = "";
- map mapvalue = $[];
- boolean remove_boot = false;
- if( size( filter( map e, solution["partitions"]:[],
- ``(e["mount"]:""==Partitions::BootMount() &&
- e["auto_added"]:false)))>0 )
- {
- foreach( map e, solution["solution","gap"]:[],
- ``{
- foreach( list a, e["added"]:[],
- ``{
- integer pindex = a[0]:0;
- if( solution["partitions",pindex,"mount"]:"" == "/" &&
- disk["cyl_count"]:0 > Partitions::BootCyl() &&
- e["end"]:0 <= Partitions::BootCyl() )
- {
- remove_boot = true;
- }
- });
- });
- }
- integer index = 0;
- if( remove_boot )
- {
- foreach( map e, solution["solution","gap"]:[],
- ``{
- list nlist = [];
- foreach( list a, e["added"]:[],
- ``{
- integer pindex = a[0]:0;
- if( solution["partitions",pindex,"mount"]:"" ==
- Partitions::BootMount() )
- {
- integer rest = a[2]:0;
- y2milestone( "remove unneeded %3 %1 cyl %2",
- e["added"]:[], rest, Partitions::BootMount() );
- list<list> nlist = filter( list l, e["added"]:[], ``(l[0]:0!=pindex));
- if( size(nlist)>0 && !e["exists"]:false )
- {
- list weight = maplist( list l, nlist, ``(l[2]:0) );
- map r = $[];
- r = distribute_space( rest, weight, nlist,
- solution["partitions"]:[] );
- nlist = eval(r["added"]:[]);
- solution["solution","gap",index,"cylinders"] =
- e["cylinders"]:0 - r["diff"]:0;
- }
- solution["solution","gap",index,"added"] = eval(nlist);
- y2milestone( "remove unneeded %2 %1", e["added"]:[],
- Partitions::BootMount() );
- }
- pindex = pindex+1;
- });
- index = index + 1;
- });
- }
- index = 0;
- foreach( map e, solution["solution","gap"]:[],
- ``{
- if( !e["exists"]:false && e["cylinders"]:0>0 )
- {
- integer increase = 0;
- list<integer> weight =
- maplist( list l, e["added"]:[],
- ``(solution["partitions",l[0]:0,"grow"]:false ? 1 : 0) );
- if( find( integer l, weight, ``(l>0) ) != nil )
- {
- map r = $[];
- r = distribute_space( e["cylinders"]:0, weight, e["added"]:[],
- solution["partitions"]:[] );
- solution["solution","gap",index,"added"] = eval(r["added"]:[]);
- solution["solution","gap",index,"cylinders"] =
- e["cylinders"]:0 - r["diff"]:0;
- y2milestone( "increase increasable p %1 cyl %2",
- solution["solution","gap",index,"added"]:[],
- solution["solution","gap",index,"cylinders"]:0 );
- }
- }
- index = index + 1;
- });
- foreach( map e, solution["solution","gap"]:[],
- ``{
- if( e["exists"]:false )
- {
- integer index = 0;
- integer pindex = e["added",0,0]:0;
- string mount = solution["partitions",pindex,"mount"]:"";
- integer fsid = Partitions::fsid_native;
- if( mount == "swap" )
- {
- fsid = Partitions::fsid_swap;
- }
- if( solution["partitions",pindex,"id"]:0 != 0 )
- {
- fsid = solution["partitions",pindex,"id"]:0;
- }
- foreach( map p, disk["partitions"]:[],
- ``{
- if( !p["delete"]:false && p["nr"]:0 == e["added",0,1]:0 )
- {
- p["format"] = solution["partitions",pindex,"format"]:true;
- if( solution["partitions",pindex,"resize"]:false == true ) {
- p["resize"] = true;
- p["region"] = solution["partitions",pindex,"region"]:[];
- }
- p["mount"] = mount;
- if (e["reuse"]:false)
- p["used_fs"] = solution["partitions",pindex,"filesystem"]:p["detected_fs"]:`reiser;
- else
- p["used_fs"] = solution["partitions",pindex,"filesystem"]:`reiser;
-
- value = solution["partitions",pindex,"fstopt"]:"";
- if( size(value)>0 )
- {
- p["fstopt"] = value;
- }
- else
- {
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- }
- mapvalue = solution["partitions",pindex,"fs_options"]:$[];
- if( size(mapvalue)>0 )
- {
- p["fs_options"] = mapvalue;
- }
- value = solution["partitions",pindex,"label"]:"";
- if( size(value)>0 )
- {
- symbol mb = solution["partitions",pindex,"mountby"]:`no_mb;
- if( mb != `no_mb ) {
- p["mountby"] = mb;
- }
- p["label"] = value;
- }
-
-
- if (solution["partitions",pindex,"loop_fs"]:false
- || solution["partitions",pindex,"crypt_fs"]:false)
- {
- //p["loop_fs"] = solution["partitions",pindex,"crypt_fs"]:false;
- p["enc_type"] = solution["partitions",pindex,"enc_type"]:`twofish;
- Storage::UpdateClassified( p["device"]:"",
- solution["partitions",pindex,"crypt_key"]:"" );
- //p["crypt"] = solution["partitions",pindex,"crypt"]:"twofish256";
- }
-
- if( p["fsid"]:0 != fsid )
- {
- p["change_fsid"] = true;
- p["ori_fsid"] = p["fsid"]:0;
- p["fsid"] = fsid;
- }
- if (solution["partitions",pindex,"lvm_group"]:"" != "")
- {
- p["used_fs"] = `unknown;
- p["fsid"] = Partitions::fsid_lvm;
- p["format"] = false;
- p["lvm_group"] = solution["partitions",pindex,"lvm_group"]:"";
- p["mount"] = "";
- p["fstype"] = "Linux LVM";
- }
- else if (solution["partitions",pindex,"evms_group"]:"" != "") {
- p["used_fs"] = `unknown;
- p["fsid"] = Partitions::fsid_lvm;
- p["format"] = false;
- string lvm = (solution["partitions",pindex,"evms_group"]:true)?("lvm2"):("lvm");
- p["evms_group"] = "evms/"+lvm+"/"+solution["partitions",pindex,"evms_group"]:"";
- p["mount"] = "";
- p["fstype"] = "EVMS";
- }
- else if (solution["partitions",pindex,"raid_name"]:"" != "")
- {
- p["used_fs"] = `unknown;
- p["fsid"] = Partitions::fsid_raid;
- p["format"] = false;
- p["raid_name"] = solution["partitions",pindex,"raid_name"]:"";
- p["raid_type"] = solution["partitions",pindex,"raid_type"]:"raid";
- p["mount"] = "";
- p["fstype"] = "Linux RAID";
- }
-
- disk["partitions",index] = p;
- y2milestone( "reuse auto partition %1", p );
- }
- index = index + 1;
- });
- }
- else
- {
- list region = [ e["start"]:0, e["end"]:0-e["start"]:0+1 ];
- map part = $[];
-
- if( e["extended"]:false && e["created"]:0 > 0 && size(e["created_primary"]:[]) == 0)
- {
- part["create"] = true;
- part["nr"] = e["created"]:0;
- part["device"] = Storage::GetDeviceName( dev, part["nr"]:-1 );
- part["region"] = eval(region);
- part["type"] = `extended;
- part["fsid"] = Partitions::fsid_extended_win;
- part["fstype"] = Partitions::FsIdToString( part["fsid"]:0 );
- y2milestone( "extended auto partition %1", part );
- partitions = add( partitions, eval(part));
- }
- foreach( list a, e["added"]:[],
- ``{
- part = $[];
- integer pindex = a[0]:0;
- string mount = solution["partitions",pindex,"mount"]:"";
- integer fsid = Partitions::fsid_native;
- part["format"] = solution["partitions",pindex,"format"]:true;
- if( mount == "swap" )
- {
- fsid = Partitions::fsid_swap;
- }
- if( solution["partitions",pindex,"filesystem_id"]:0 != 0 )
- {
- fsid = solution["partitions",pindex,"filesystem_id"]:0;
- if( !haskey( solution["partitions",pindex]:$[], "filesystem" ))
- {
- part["format"] = false;
- }
- y2milestone( "partition id %1 format %2 part %3", fsid,
- part["format"]:false,
- solution["partitions",pindex]:$[] );
- }
- part["create"] = true;
- part["nr"] = a[1]:0;
- part["device"] = Storage::GetDeviceName( dev, part["nr"]:0 );
- region[1] = a[2]:0;
- part["region"] = eval(region);
- region[0] = region[0]:0 + region[1]:0;
- part["type"] = `primary;
- if( e["extended"]:false )
- {
- part["type"] = `logical;
- }
-
- if(contains(e["created_primary"]:[], a[1]:0 ))
- {
- part["type"] = `primary;
- }
-
- part["mount"] = mount;
- symbol mb = solution["partitions",pindex,"mountby"]:`no_mb;
- if( mb != `no_mb ) {
- part["mountby"] = mb;
- }
- part["used_fs"] =
- solution["partitions",pindex,"filesystem"]:((mount == "swap")?(`swap):(`reiser));
- value = solution["partitions",pindex,"fstopt"]:"";
- if( size(value)>0 )
- {
- part["fstopt"] = value;
- }
- else
- {
- part["fstopt"] = FileSystems::DefaultFstabOptions( part );
- }
-
- mapvalue = solution["partitions",pindex,"fs_options"]:$[];
- if( size(mapvalue)>0 )
- {
- part["fs_options"] = mapvalue;
- }
-
- if (solution["partitions",pindex,"loop_fs"]:false
- || solution["partitions",pindex,"crypt_fs"]:false)
- {
- //part["loop_fs"] = solution["partitions",pindex,"crypt_fs"]:false;
- part["enc_type"] = solution["partitions",pindex,"enc_type"]:`twofish;
- Storage::UpdateClassified( part["device"]:"",
- solution["partitions",pindex,"crypt_key"]:"" );
- //part["crypt"] = solution["partitions",pindex,"crypt"]:"twofish256";
- }
-
- value = solution["partitions",pindex,"label"]:"";
- if( size(value)>0 )
- {
- part["label"] = value;
- }
- part["fsid"] = fsid;
- part["fstype"] = Partitions::FsIdToString( fsid );
- if (solution["partitions",pindex,"lvm_group"]:"" != "")
- {
- part["used_fs"] = `unknown;
- part["fsid"] = Partitions::fsid_lvm;
- part["format"] = false;
- part["lvm_group"] = solution["partitions",pindex,"lvm_group"]:"";
- part["mount"] = "";
- part["fstype"] = "Linux LVM";
- }
- else if (solution["partitions",pindex,"evms_group"]:"" != "") {
- part["used_fs"] = `unknown;
- part["fsid"] = Partitions::fsid_lvm;
- part["format"] = false;
- part["evms_group"] = solution["partitions",pindex,"evms_group"]:"";
- part["mount"] = "";
- part["fstype"] = "EVMS";
- }
- else if (solution["partitions",pindex,"raid_name"]:"" != "")
- {
- part["used_fs"] = `unknown;
- part["fsid"] = Partitions::fsid_raid;
- part["format"] = false;
- part["raid_name"] = solution["partitions",pindex,"raid_name"]:"";
- part["raid_type"] = solution["partitions",pindex,"raid_type"]:"raid";
- part["mount"] = "";
- part["fstype"] = "Linux RAID";
- }
-
- y2milestone( "auto partition %1", part );
- partitions = add( partitions, eval(part));
-
- if (a[1]:0 + 1 == e["created"]:0 && e["extended"]:false )
- {
- part = $[];
- list ext_region = [ region[0]:0, e["end"]:0-region[0]:0+1 ];
- part["create"] = true;
- part["nr"] = e["created"]:0;
- part["device"] = Storage::GetDeviceName( dev, part["nr"]:-1 );
- part["region"] = ext_region;
- part["type"] = `extended;
- part["fsid"] = Partitions::fsid_extended_win;
- part["fstype"] = Partitions::FsIdToString( part["fsid"]:0 );
- y2milestone( "extended auto partition %1", part );
- partitions = add( partitions, eval(part));
- }
- });
- partitions = sort( map a, map b, partitions, ``(a["nr"]:0<b["nr"]:0));
- }
- });
- disk["partitions"] = union( disk["partitions"]:[], partitions );
- y2milestone( "disk %1", disk );
- return( disk );
- }
-
- define map find_matching_partition_size(map gap, integer nr)
- {
- list mg = filter(map g, gap["gap"]:[], ``(g["nr"]:-1 == nr && g["reuse"]:false));
- y2milestone("usepart partition: %1", mg[0]:$[]);
- return mg[0]:$[];
- }
-
- /**
- * Add Cylinder Information
- */
- define map add_cylinder_info( map conf, map gap )
- ``{
- integer big_cyl = 4 * 1024 * 1024 * 1024;
- integer cyl_size = gap["cyl_size"]:1;
- /*
- // FIXME: Why is sorting needed here?
- conf["partitions"] =
- sort( map a, map b, conf["partitions"]:[],
- ``({
- if( a["max_cyl"]:big_cyl != b["max_cyl"]:big_cyl )
- return( a["max_cyl"]:big_cyl < b["max_cyl"]:big_cyl );
- else
- return( a["size"]:0 > b["size"]:0 );
- }));
- */
- y2milestone( "parts %1", conf["partitions"]:[] );
- integer sum = 0;
- conf["partitions"] = maplist( map p, conf["partitions"]:[],
- ``{
- sum = sum + p["pct"]:0;
- p["cylinders"] = (p["size"]:0+cyl_size-1)/cyl_size;
-
- // p["cylinders"] = (p["size"]:0)/cyl_size;
-
- map mg = find_matching_partition_size(gap,p["usepart"]:0);
- if (mg != $[])
- {
- p["cylinders"] = mg["cylinders"]:0;
- p["size"] = mg["size"]:0;
- if (p["usepart"]:0< gap["max_primary"]:0)
- {
- p["partition_type"] = "primary";
- }
- }
-
- if( p["cylinders"]:0 == 0 )
- {
- p["cylinders"] = 1;
- }
- return( p );
- });
- y2milestone( "sum %1", sum );
- y2milestone( "parts %1", conf["partitions"]:[] );
- if( sum>100 )
- {
- integer rest = sum - 100;
- conf["partitions"] = maplist( map p, conf["partitions"]:[],
- ``{
- if( haskey( p, "pct" ) )
- {
- integer pct = p["pct"]:0;
- integer diff = ((rest * pct) + sum/2) / sum;
- sum = sum - pct;
- rest = rest - diff;
- p["pct"] = pct - diff;
- }
- return( p );
- });
- }
- conf["partitions"] = maplist( map p, conf["partitions"]:[],
- ``{
- if( haskey( p, "pct" ) )
- {
- integer cyl = gap["sum"]:0 / 100 * p["pct"]:0;
- cyl = (cyl+cyl_size/2) / cyl_size;
- if( cyl == 0 )
- {
- cyl = 1;
- }
- p["want_cyl"] = cyl;
- }
- if( p["max"]:0 > 0 )
- {
- integer cyl = (p["max"]:0+cyl_size-1) / cyl_size;
- p["size_max_cyl"] = cyl;
- if( p["want_cyl"]:0 > cyl )
- {
- p["want_cyl"] = cyl;
- }
- }
- return( p );
- });
- y2milestone( "parts %1", conf["partitions"]:[] );
- return( conf );
- }
-
-
- /**
- * Compute perfect partition list
- * @param ps Partition List from control file
- * @param g Calculated Gaps
- * @return map Best partition list using the gaps
- */
- define map get_perfect_list( list ps, map g ) {
- y2milestone( "requested partitions %1", ps );
- y2milestone( "calculated gaps %1", g );
-
- /**
- * If gaps are available
- * AND (
- * extended partitions are possible and there are
- * primaries left and number of requested partitions(+1) is less than all available
- * primaries and logical slots
- * OR
- * extended is not possible and number of requested partitions is less than all
- * available primaries and logical slots )
- */
- if( size(g["gap"]:[])>0 &&
- ((g["extended_possible"]:false &&
- // size(g["free_pnr"]:[])>0 && // reusing all 4 primaries will fail with this
- size(ps)+1 <= size(g["ext_pnr"]:[])+size(g["free_pnr"]:[])) ||
- (!g["extended_possible"]:false &&
- size(ps) <= size(g["ext_pnr"]:[])+size(g["free_pnr"]:[]))) )
- {
- map lg = (map) eval(g);
-
- // prepare local gap var
- lg["gap"] = maplist( map e, lg["gap"]:[],
- ``{
- e["orig_cyl"] = e["cylinders"]:0;
- e["added"] = [];
- return( e );
- });
- lg["procpart"] = 0;
-
- list lp = (list) eval(ps);
-
- if( g["extended_possible"]:false &&
- size(ps)+1>=size(g["free_pnr"]:[]) &&
- size(filter(map up, (list<map>)ps, ``(
- up["partition_type"]:"none" == "primary" ||
- contains(lg["free_pnr"]:[], up["partition_nr"]:0) ))) == 0
- )
- {
- y2milestone( "creating extended" );
- integer index = 0;
- foreach( map e, lg["gap"]:[],
- ``{
- if( !e["exists"]:false )
- {
- map gap = (map) eval(lg);
- gap["gap",index,"created"] = gap["free_pnr",0]:1;
- gap["free_pnr"] = remove( gap["free_pnr"]:[1], 0 );
- gap["gap",index,"extended"] = true;
- add_part_recursive( ps, gap );
- }
- index = index+1;
- });
- }
- else
- {
- y2milestone( "not creating extended now" );
- add_part_recursive( ps, lg );
- }
- }
- map ret = $[];
- if( size(cur_gap)>0 )
- {
- ret["weight"] = cur_weight;
- ret["solution"] = eval(cur_gap);
- ret["partitions"] = eval(ps);
- }
- y2milestone( "ret weight %1", ret["weight"]:-1000000 );
- y2milestone( "ret solution %1", ret["solution","gap"]:[] );
- return( ret );
- }
-
-
-
- /**
- * Recursive Adding of partitions
- * @param ps Partition list from control file
- * @param g Calculated gaps
- * @return void
- */
- define void add_part_recursive( list ps, map g )
- ``{
- y2milestone( "partition index %1", g["procpart"]:0 );
- y2milestone( "partitions %1", ps );
- y2milestone( "gap %1", g );
-
- // creation_needed indicates the case, that we do not
- // create a single partition but are reusing some
- boolean creation_needed = false;
- foreach( map p, (list<map>)ps, ``{
- if( p["create"]:true == true ) {
- creation_needed = true;
- }
- });
- y2milestone("creation is needed? %1",creation_needed);
-
-
- map lg = (map) eval(g);
- integer gindex = 0;
- integer pindex = lg["procpart"]:0;
- map part = ps[pindex]:$[];
- lg["procpart"] = pindex + 1;
- y2milestone( "working on partition %1", part );
- foreach( map e, lg["gap"]:[],
- ``{
- y2milestone( "start: gap section %1", e );
-
- if( part["max_cyl"]:0 <= e["end"]:0 &&
- part["cylinders"]:0 <= e["cylinders"]:0 &&
- (!e["extended"]:false && (size(lg["free_pnr"]:[])>0 || ! creation_needed ) ||
- e["extended"]:false && size(lg["ext_pnr"]:[])>0)
- )
- {
- map llg = (map) eval(lg);
-
- list addl = [ pindex ];
-
- // number of needed primaries by user
- integer sp = size(filter(map up, (list<map>)ps,
- ``(up["partition_type"]:"none" == "primary" ||
- contains(llg["free_pnr"]:[], up["partition_nr"]:0))));
-
- y2milestone("number of primaries requested: %1", sp );
- integer cp = 0;
- foreach(map gg, llg["gap"]:[], ``{
- cp = cp + size(gg["created_primary"]:[]);
- });
-
- boolean ex = false;
- y2milestone("number of created primaries: %1", cp );
-
- // Extended
- if( llg["extended_possible"]:false &&
- !e["extended"]:false &&
- size(ps)+1>=size(llg["free_pnr"]:[]) && // maybe not needed
- cp == sp && sp > 0 )
- {
- y2milestone( "creating extended" );
-
- map gap = (map) eval(lg);
- llg["gap",gindex,"created"] = llg["free_pnr",0]:1;
- llg["free_pnr"] = remove( llg["free_pnr"]:[1], 0 );
- llg["gap",gindex,"extended"] = true;
- // reset
- llg["procpart"] = pindex ;
- ex = true;
-
- }
- // Logical
- else if( e["extended"]:false ) // ||
- /*
- ( ps[pindex,"partition_type"]:"none" != "primary" &&
- ps[pindex,"partition_type"]:"none" != "extended")
- )
- */
- {
- if (!e["reuse"]:false)
- {
- addl = add( addl, llg["ext_pnr",0]:5 );
- llg["ext_pnr"] = remove( llg["ext_pnr"]:[0], 0 );
- } else {
- addl = add( addl, e["nr"]:0 );
- }
- }
- // Primary
- else
- {
- if (e["exists"]:false)
- {
- addl = add( addl, e["nr"]:0 );
- llg["gap",gindex,"created_primary"] = add(llg["gap",gindex,"created_primary"]:[],
- e["nr"]:0 );
- } else {
- addl = add( addl, llg["free_pnr",0]:1 );
- llg["gap",gindex,"created_primary"] = add(llg["gap",gindex,"created_primary"]:[],
- llg["free_pnr",0]:1 );
- llg["free_pnr"] = remove( llg["free_pnr"]:[0], 0 );
- }
-
- }
-
- if (!ex)
- {
- llg["gap",gindex,"added"] =
- add( llg["gap",gindex,"added"]:[], addl );
- }
-
- if (!ex) {
- if( e["exists"]:false )
- {
- llg["gap",gindex,"cylinders"] = 0;
- }
- else
- {
- llg["gap",gindex,"cylinders"] =
- llg["gap",gindex,"cylinders"]:0 - part["cylinders"]:0;
- }
- }
-
- if( pindex+1 < size(ps) || ex )
- {
- add_part_recursive( ps, llg );
- }
- else
- {
- map ng = normalize_gaps(ps, llg);
- integer val = do_weighting( ps, ng );
- y2milestone( "val %1 cur_weight %2 size %3", val, cur_weight, size(cur_gap));
- if( val > cur_weight || size(cur_gap)==0 )
- {
- cur_weight = val;
- cur_gap = (map)eval(ng);
- }
- }
- }
- gindex = gindex+1;
- });
-
- };
-
-
-
- /**
- * Normalize Gaps
- */
- define map normalize_gaps( list ps, map g )
- ``{
- y2milestone( "normalize_gaps: gap %1", g );
- integer gindex = 0;
- integer pindex = 0;
- foreach( map e, g["gap"]:[],
- ``{
- y2milestone( "gap section %1", e );
- if( e["exists"]:false )
- {
- if( size(e["added"]:[])>0 && size(e["added",0]:[])==2 )
- {
- e["added",0] = add( e["added",0]:[], e["orig_cyl"]:1 );
- }
- }
- else
- {
- integer rest = e["cylinders"]:0;
- integer needed = 0;
- integer tidx = 0;
- foreach( list p, e["added"]:[],
- ``{
- tidx = p[0]:0;
- if( ps[tidx,"want_cyl"]:0 > ps[tidx,"cylinders"]:0 )
- {
- needed = needed + ps[tidx,"want_cyl"]:0 -
- ps[tidx,"cylinders"]:0;
- }
- });
- y2milestone( "needed %1 rest %2", needed, rest );
- if( needed > rest )
- {
- list tr = [];
- list weight =
- maplist( list l, e["added"]:[],
- ``({
- integer idx = l[0]:0;
- integer d = ps[idx,"want_cyl"]:0 -
- ps[idx,"cylinders"]:0;
- if( d>0 )
- {
- l = add( l, ps[idx,"cylinders"]:0 );
- }
- tr = add( tr, l );
- return( d>0 ? d : 0 );
- }));
- y2milestone( "tr %1", tr );
- map r = $[];
- r = distribute_space( rest, weight, tr, ps );
- g["gap",gindex,"added"] = eval(r["added"]:[]);
- g["gap",gindex,"cylinders"] = e["cylinders"]:0 - r["diff"]:0;
- y2milestone( "partly satisfy %1 cyl %2", g["gap",gindex,"added"]:[],
- g["gap",gindex,"cylinders"]:0 );
- }
- else
- {
- g["gap",gindex,"cylinders"] = e["cylinders"]:0 - needed;
- }
-
- pindex = 0;
- foreach( list p, g["gap",gindex,"added"]:[],
- ``{
- if( size(p)<3 )
- {
- tidx = p[0]:0;
- if( ps[tidx,"want_cyl"]:0 > ps[tidx,"cylinders"]:0 )
- {
- p = add( p, ps[tidx,"want_cyl"]:0 );
- }
- else
- {
- p = add( p, ps[tidx,"cylinders"]:0 );
- }
- g["gap",gindex,"added",pindex] = p;
- y2milestone( "satisfy p %1 cyl %2", p, e["cylinders"]:0 );
- }
- pindex = pindex+1;
- });
- y2milestone( "added %1", g["gap",gindex,"added"]:[] );
- }
- gindex = gindex + 1;
- });
- gindex = 0;
- foreach( map e, g["gap"]:[],
- ``{
- if( !e["exists"]:false && e["cylinders"]:0>0 )
- {
- list<integer> weight = maplist( list l, e["added"]:[],
- ``(ps[l[0]:0,"size"]:0==0 ? 1 : 0) );
- if( find( integer l, weight, ``(l>0) ) != nil )
- {
- map r = $[];
- r = distribute_space( e["cylinders"]:0, weight, e["added"]:[],
- ps );
- g["gap",gindex,"added"] = eval(r["added"]:[]);
- g["gap",gindex,"cylinders"] = e["cylinders"]:0 - r["diff"]:0;
- y2milestone( "increase max p %1 cyl %2", g["gap",gindex,"added"]:[],
- g["gap",gindex,"cylinders"]:0 );
- }
- }
- gindex = gindex + 1;
- });
- gindex = 0;
- foreach( map e, g["gap"]:[],
- ``{
- if( !e["exists"]:false && e["cylinders"]:0>0 &&
- e["cylinders"]:0 < g["disk_cyl"]:0/20 )
- {
- list weight = maplist( list l, e["added"]:[], ``(l[2]:0) );
- map r = $[];
- r = distribute_space( e["cylinders"]:0, weight, e["added"]:[], ps );
- g["gap",gindex,"added"] = eval(r["added"]:[]);
- g["gap",gindex,"cylinders"] = e["cylinders"]:0 - r["diff"]:0;
- y2milestone( "close small gap p %1 cyl %2", g["gap",gindex,"added"]:[],
- g["gap",gindex,"cylinders"]:0 );
- }
- gindex = gindex + 1;
- });
- y2milestone( "gap %1", g );
- return( g );
- };
-
-
- /**
- * Distribute Spaces
- */
- define map distribute_space( integer rest, list weights, list added, list ps )
- ``{
- integer diff_sum = 0;
- integer sum = 0;
- integer index = 0;
- integer pindex = 0;
- y2milestone( "rest %1 weights %2 added %3", rest, weights, added );
- foreach( list p, (list<list>)added,
- ``{
- pindex = p[0]:0;
- if( ps[pindex,"size_max_cyl"]:0==0 || ps[pindex,"grow"]:false ||
- ps[pindex,"size_max_cyl"]:0 > p[2]:0 )
- {
- sum = sum + weights[index]:0;
- }
- index = index+1;
- });
- index = 0;
- y2milestone( "sum %1 rest %2 added %3", sum, rest, added );
- foreach( list p, (list<list>)added,
- ``{
- pindex = p[0]:0;
- if( size(p)==3 && sum>0 &&
- (ps[pindex,"size_max_cyl"]:0==0 || ps[pindex,"grow"]:false ||
- ps[pindex,"size_max_cyl"]:0 > p[2]:0) )
- {
- integer diff = ((rest*weights[index]:0) + sum/2) / sum;
- if( ps[pindex,"size_max_cyl"]:0>0 &&
- !ps[pindex,"grow"]:false &&
- diff > ps[pindex,"size_max_cyl"]:0-p[2]:0 )
- {
- diff = ps[pindex,"size_max_cyl"]:0-p[2]:0;
- }
- sum = sum - weights[index]:0;
- rest = rest - diff;
- added[index,2] = added[index,2]:0 + diff;
- diff_sum = diff_sum + diff;
- y2milestone( "sum %1 rest %2 diff %3 added %4", sum, rest, diff,
- added[index]:[] );
- }
- index = index+1;
- });
- map ret = $[ "added":added, "diff" : diff_sum ];
- y2milestone( "ret (distribute_space) %1", ret );
- return( ret );
- }
-
-
- /**
- * Calculate plan weights
- */
- define integer do_weighting( list ps, map g )
- ``{
- y2milestone( "gap %1", g["gap"]:[] );
- integer ret = 0;
- integer index = 0;
- if( cur_mode == `free )
- {
- ret = 0;
- }
- if( cur_mode == `reuse )
- {
- ret = ret - 100;
- }
- else if( cur_mode == `resize )
- {
- ret = ret - 1000;
- }
- else if( cur_mode == `desparate )
- {
- ret = ret - 1000000;
- }
- y2milestone( "weight after mode ret %1", ret );
- foreach( map e, g["gap"]:[],
- ``{
- y2milestone( "added %1", e["added"]:[] );
- if( !e["exists"]:false && e["cylinders"]:0 > 0 )
- {
- ret = ret - 5;
- if( e["cylinders"]:0 < g["disk_cyl"]:0/20 )
- {
- ret = ret - 10;
- }
- y2milestone("weight (cyl) %1", ret );
- }
- y2milestone( "weight after gaps %1", ret );
- foreach( list p, e["added"]:[],
- ``{
- index = p[0]:0;
- if( e["exists"]:false && ps[index,"mount"]:""=="swap" &&
- e["swap"]:false )
- {
- ret = ret + 100;
- y2milestone( "weight after swap reuse %1", ret );
- }
- if( ps[index,"want_cyl"]:0>0 )
- {
- integer diff = ps[index,"want_cyl"]:0 - p[2]:0;
- integer normdiff = diff * 100 / p[2]:0;
- if( diff < 0 )
- {
- normdiff = -normdiff;
- }
- else if( diff > 0 )
- {
- normdiff = normdiff / 10;
- }
- ret = ret - normdiff;
- ret = ret + ps[index,"want_cyl"]:0*g["cyl_size"]:1 /
- (100 * 1024 * 1024);
- y2milestone( "after pct parts %1", ret );
- }
- if( ps[index,"size"]:0==0 )
- {
- ret = ret + p[2]:0 * g["cyl_size"]:1 / (50 * 1024 * 1024);
- y2milestone( "after maximizes parts %1", ret );
- }
- if( ps[index,"size_max_cyl"]:0 > 0 &&
- ps[index,"size_max_cyl"]:0 < p[2]:0 )
- {
- integer diff = p[2]:0 - ps[index,"size_max_cyl"]:0;
- integer normdiff = diff * 100 / ps[index,"size_max_cyl"]:0;
- ret = ret - normdiff;
- y2milestone( "after maximal size %1", ret );
- }
- });
- /*
- if( e["cylinders"]:0 > 0 )
- {
- y2milestone("ret (before rounding): %1", ret);
- ret = ret - (e["cylinders"]:0 * g["cyl_size"]:1) / (1024*1024*1024);
- y2milestone("weight (after rounding): %1", ret);
- }
- */
- });
- y2milestone( "weight: %1", ret );
- return( ret );
- };
-
- /**
- * Remove partitions
- * @param disk disk data
- * @param pm partitioning as in the control file.
- * @return map the new partition map with removed partitions
- */
- define map remove_possible_partitions( map disk , map pm)
- {
- boolean remove_special_partitions = pm["remove_special_partitions"]:false;
- list keep_partition_num = pm["keep_partition_num"]:[];
- list keep_partition_id = pm["keep_partition_id"]:[];
- list keep_partition_fsys = pm["keep_partition_fsys"]:[];
-
- // Special partitions
- list nodelpart = [ 0x12, 0xde, 257 ];
-
- // Handle <usepart> which is analog to create=false and partition_nr>0
- foreach(map p, pm["partitions"]:[], ``{
- if (p["usepart"]:0 != 0 )
- keep_partition_num=add(keep_partition_num, p["usepart"]:0 );
- });
-
- map ret = (map)disk;
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- integer fsid = p["fsid"]:0;
- if( (remove_special_partitions ||
- !contains( nodelpart, fsid ) ) &&
- p["type"]:`primary != `extended &&
- !contains( keep_partition_num, p["nr"]:0 ) &&
- !contains( keep_partition_id, fsid ) &&
- !contains( keep_partition_fsys, p["used_fs"]:`none ))
- {
- p["delete"] = true;
- if (haskey(p, "raid_name")) {
- p["old_raid_name"] = p["raid_name"]:"";
- p=remove(p, "raid_name");
- }
- }
- return( p );
- });
- integer max_prim = Partitions::MaxPrimary(disk["label"]:"msdos");
-
- // delete extended if no logical remain
- if( size( filter( map p, ret["partitions"]:[],
- ``(p["type"]:`primary == `extended)))>0 &&
- size( filter( map p, ret["partitions"]:[],
- ``(p["nr"]:0>max_prim && !p["delete"]:false) ))==0 )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["type"]:`primary == `extended )
- {
- p["delete"] = true;
- }
- return( p );
- });
- }
- y2milestone("after removal: %1", ret);
- return( ret );
- }
-
-
-
- /*
- define map remove_possible_partitions( map disk, map conf )
- ``{
- list nodelpart = [ 0x12, 0xde, 257 ];
- map ret = (map)eval(disk);
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- integer fsid = p["fsid"]:0;
- if( (conf["remove_special_partitions"]:false ||
- !contains( nodelpart, fsid ) ) &&
- p["type"]:`primary != `extended &&
- !contains( conf["keep_partition_num"]:[], p["nr"]:0 ) &&
- !contains( conf["keep_partition_id"]:[], fsid ) &&
- !contains( conf["keep_partition_fsys"]:[], p["used_fs"]:`none ))
- {
- p["delete"] = true;
- }
- return( p );
- });
- integer max_prim = Partitions::MaxPrimary(disk["label"]:"msdos");
- if( size( filter( map p, ret["partitions"]:[],
- ``(p["type"]:`primary == `extended)))>0 &&
- size( filter( map p, ret["partitions"]:[],
- ``(p["nr"]:0>max_prim && !p["delete"]:false) ))==0 )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["type"]:`primary == `extended )
- {
- p["delete"] = true;
- }
- return( p );
- });
- }
- return( ret );
- };
- */
-
-
- /**
- * Try resizing windows partition
- *
- */
- define map try_resize_windows( map disk )
- ``{
- integer cyl_size = disk["cyl_size"]:1;
- map win = $[];
- map ret = (map)eval(disk);
-
- ret["partitions"] = maplist( map p, ret["partitions"]:[], ``{
- integer fsid = p["fsid"]:0;
- if( Partitions::IsDosPartition( fsid ) )
- {
- integer psize = (p["region",0]:0 + p["region",1]:1 - 1) * cyl_size;
- win = Storage::GetFreeSpace( p["device"]:"", psize, `fat32,
- false );
- y2milestone( "win=%1", win );
- if( win != nil && psize > 300*1024*1024 )
- {
- p["winfo"] = win;
- p["region",1] = (win["new_size"]:0 + cyl_size - 1) / cyl_size;
- y2milestone( "win part %1", p );
- }
- }
- return( p );
- });
- return( ret );
- };
-
-
- /**
- * Collect gap information
- *
- */
- define list<map> get_gaps( integer start, integer end,
- map pd,
- list<map> part,
- boolean add_exist_linux )
- ``{
- y2milestone("partitions: %1", pd["partitions"]:[] );
- list<integer> usepart_p = maplist(map pa, pd["partitions"]:[],
- ``{
- return pa["usepart"]:0;
- });
- list<integer> reuse = filter(integer i, usepart_p, ``(i!=0));
-
- y2milestone("reuse: %1", reuse);
-
- y2milestone( "start %1 end %2 add_exist %3", start, end, add_exist_linux );
- list<map> ret = [];
- map entry = $[];
- foreach( map p, part,
- ``{
- integer s = p["region",0]:0;
- integer e = s + p["region",1]:1 - 1;
- entry = $[];
- y2milestone("Getting gap from part: %1", p );
- y2milestone("start %1 s %2 e %3", start, s, e );
- if( start < s )
- {
- entry["start"] = start;
- entry["end"] = s-1;
- ret = add( ret, eval(entry) );
- }
- if( add_exist_linux &&
- (p["fsid"]:0==Partitions::fsid_native ||
- p["fsid"]:0==Partitions::fsid_swap) )
- {
- entry["swap"] = p["fsid"]:0==Partitions::fsid_swap;
- entry["start"] = s;
- entry["end"] = e;
- entry["exists"] = true;
- entry["nr"] = p["nr"]:0;
- ret = add( ret, entry );
- }
-
- if (contains(reuse, p["nr"]:0))
- {
- // This partition is to be used as specified in the control file
- entry["swap"] = p["fsid"]:0==Partitions::fsid_swap;
- entry["start"] = s;
- entry["end"] = e;
- entry["exists"] = true;
- entry["reuse"] = true;
- entry["nr"] = p["nr"]:0;
- ret = add( ret, entry );
- }
-
- start = e+1;
- });
- if( start < end )
- {
- entry = $[];
- entry["start"] = start;
- entry["end"] = end;
- ret = add( ret, entry );
- }
- y2milestone( "ret %1", ret );
- return( ret );
- }
-
-
- /**
- * Collect gap information
- *
- */
- define map get_gap_info( map disk, map pd, boolean add_exist_linux )
- ``{
- map ret = $[];
- list<map> gap = [];
- list<map> plist = filter( map p, disk["partitions"]:[], ``(!p["delete"]:false) );
- plist = sort( map a, map b, plist, ``(a["region",0]:0<b["region",0]:0) );
- list exist_pnr = sort( maplist( map e, plist, ``(e["nr"]:0) ));
- integer max_prim = Partitions::MaxPrimary(disk["label"]:"msdos");
- boolean has_ext = Partitions::HasExtended( disk["label"]:"msdos" );
-
- // check if we support extended partitions
- if( has_ext )
- {
- // see if disk has an extended already
- map ext = filter( map p, plist,
- ``(p["type"]:`primary == `extended))[0]:$[];
- ret["extended_possible"] = size(ext)==0;
- if( size(ext)>0 )
- {
- gap = get_gaps( ext["region",0]:0,
- ext["region",0]:0 + ext["region",1]:1-1,
- pd,
- filter( map p, plist, ``(p["nr"]:0>max_prim)),
- add_exist_linux );
- gap = maplist( map e, gap,
- ``{
- e["extended"]=true;
- return e;
- });
- plist = filter( map p, plist, ``(p["nr"]:0<=max_prim));
- }
- }
- else
- {
- ret["extended_possible"] = false;
- }
-
- gap = (list<map>)union( gap,
- get_gaps( 0, disk["cyl_count"]:1-1, pd, plist, add_exist_linux ));
- integer av_size = 0;
- gap = maplist( map e, gap,
- ``{
- e["cylinders"] = e["end"]:0 - e["start"]:0 + 1;
- e["size"] = e["cylinders"]:0 * disk["cyl_size"]:1;
- av_size = av_size + e["size"]:0;
- return( e );
- });
- gap = maplist( map e, gap,
- ``{
- e["sizepct"] = (e["size"]:0 * 201 / 2) / av_size;
- if( e["sizepct"]:0 == 0 )
- {
- e["sizepct"] = 1;
- }
- return( e );
- });
- ret["cyl_size"] = disk["cyl_size"]:1;
- ret["disk_cyl"] = disk["cyl_count"]:1;
- ret["max_primary"] = disk["max_primary"]:0;
- ret["sum"] = av_size;
- integer max_pnr = max_prim;
- integer pnr = 1;
- list free_pnr = [];
- y2milestone( "exist_pnr %1", exist_pnr );
- while( pnr<=max_pnr )
- {
- if( !contains( exist_pnr, pnr ) )
- {
- free_pnr = add( free_pnr, pnr );
- }
- pnr = pnr + 1;
- }
- ret["free_pnr"] = free_pnr;
- list<integer> ext_pnr = [ 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];
- integer max_logical = disk["max_logical"]:15;
- if( max_logical<63 )
- {
- ext_pnr = filter( integer i, ext_pnr, ``(i<=max_logical));
- }
- if( !ret["extended_possible"]:false )
- {
- if( !has_ext )
- {
- ext_pnr = [];
- }
- else
- {
- integer maxext = exist_pnr[size(exist_pnr)-1]:4;
- pnr = 5;
- while( pnr<=maxext )
- {
- ext_pnr = remove( ext_pnr, 0 );
- pnr = pnr+1;
- }
- }
- }
- ret["ext_pnr"] = ext_pnr;
-
- ret["gap"] = sort(map a, map b, gap, ``(a["start"]:0<b["start"]:0));
- y2milestone( "ret %1", ret );
- return( ret );
- }
-
- }
-
-