home *** CD-ROM | disk | FTP | other *** search
Text File | 2006-11-29 | 106.1 KB | 3,712 lines |
- /*
- *************************************************************
- *
- * YaST2 SuSE Labs -o)
- * -------------------- /\\
- * _\_v
- * www.suse.de / www.suse.com
- * ----------------------------------------------------------
- *
- * Author: Thomas Fehr <fehr@suse.de>
- *
- * Description: Make a proposal for partitioning
- *
- *
- *************************************************************
-
- $Id: do_proposal_flexible.ycp 33906 2006-10-30 18:01:58Z fehr $
- */
- {
-
- textdomain "storage";
-
- import "FileSystems";
- import "Partitions";
- import "Storage";
- import "ProductFeatures";
-
- include "partitioning/partition_defines.ycp";
-
- map read_partition_config( string fpath );
- map read_partition_xml_config();
- map get_gap_info( map disk, 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, string vgname );
- 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 = $[];
- integer big_cyl = 4 * 1024 * 1024 * 1024;
-
- define boolean ignore_disk( string dev, map entry, boolean soft )
- ``{
- boolean ret = !Storage::IsPartitionable( entry ) ||
- entry["readonly"]:false || Arch::s390();
- if( !ret && Arch::ia64() && entry["label"]:"gpt"!="gpt" )
- {
- ret = true;
- }
- if( !ret && soft && Arch::board_iseries () && search( dev, "/dev/sd" )==0 )
- {
- ret = true;
- }
- if( !ret && soft && (entry["softraiddisk"]:false||entry["hotpluggable"]:false) )
- {
- ret = true;
- }
- if( !ret && soft && contains( Storage::NoProposeDisks(), dev ))
- {
- ret = true;
- }
- if( !ret && soft )
- ret = entry["used_by_type"]:`UB_NONE != `UB_NONE;
- if( ret )
- {
- y2milestone( "ignoring disk %1 soft %2", dev, soft );
- }
- return( ret );
- };
-
- define string pinfo_name()
- ``{
- return( "/part.info" );
- }
-
- define boolean has_flex_proposal()
- ``{
- boolean ret = (integer)SCR::Read( .target.size, pinfo_name() )>0;
- return( ret );
- }
-
- boolean need_boot( map disk )
- {
- return( Partitions::NeedBoot() ||
- disk["type"]:`CT_UNKNOWN == `CT_DMRAID );
- }
-
- define map try_add_boot( map conf, map disk, boolean force )
- ``{
- boolean boot =
- size(filter( map e, conf["partitions"]:[],
- ``(e["mount"]:""==Partitions::BootMount()))) > 0;
- boolean root = size(filter( map e, conf["partitions"]:[],
- ``(e["mount"]:""=="/"))) > 0;
- map tc = conf;
- y2milestone( "try_add_boot conf %1", conf );
- y2milestone( "try_add_boot boot %1 root %2 force %3", boot, root, force );
- if( !boot && (root||force) &&
- (disk["cyl_count"]:0>Partitions::BootCyl() || need_boot(disk)) )
- {
- map pb = $[];
- pb["mount"] = Partitions::BootMount();
- pb["size"] = Partitions::MinimalNeededBootsize();
- pb["fsys"] = Partitions::DefaultBootFs();
- pb["id"] = Partitions::FsidBoot();
- pb["auto_added"] = true;
- pb["max_cyl"] = Partitions::BootCyl();
- pb["primary"] = Partitions::BootPrimary();
- pb["maxsize"] = 500*1024*1024;
- tc["partitions"] = add( tc["partitions"]:[], pb );
- y2milestone( "try_add_boot disk_cyl %1 boot_cyl %2 need_boot %3 typ %4",
- disk["cyl_count"]:0, Partitions::BootCyl(),
- Partitions::NeedBoot(), disk["type"]:`CT_UNKNOWN );
- y2milestone( "try_add_boot boot added automagically pb %1", pb );
- }
- return( tc );
- }
-
- define map do_flexible_disk( map disk )
- ``{
- string dev = disk["device"]:"";
- y2milestone( "do_flexible_disk dev %1", dev );
- y2milestone( "do_flexible_disk parts %1", disk["partitions"]:[] );
- map ret = $[];
- ret["ok"] = false;
- map conf = read_partition_config( pinfo_name() );
- map solutions = $[];
-
- if( size(conf)>0 && Storage::IsPartitionable( disk ))
- {
- y2milestone( "do_flexible_disk processing disk %1", dev );
- map tc = try_add_boot( conf, disk, false );
- cur_mode = `free;
- cur_gap = $[];
- map gap = get_gap_info( disk, false );
- tc = add_cylinder_info( tc, gap );
- map sol = get_perfect_list( tc["partitions"]:[], gap );
- if( size(sol)>0 )
- {
- sol["disk"] = eval(disk);
- ret["ok"] = true;
- ret["disk"] = process_partition_data( dev, sol, "" );
- ret["weight"] = sol["weight"]:-1;
- }
- }
- y2milestone( "do_flexible_disk ret %1", ret["ok"]:false );
- if( ret["ok"]:false )
- {
- y2milestone( "do_flexible_disk weight %1", ret["weight"]:-2 );
- y2milestone( "do_flexible_disk disk %1", ret["disk"]:$[] );
- }
- return( ret );
- }
-
- define map do_flexible_disk_conf( map disk, map co, boolean ignore_boot,
- boolean reuse )
- ``{
- string dev = disk["device"]:"";
- y2milestone( "do_flexible_disk_conf dev %1 ignore_boot %2 reuse %3",
- dev, ignore_boot, reuse );
- map conf = co;
- if( !ignore_boot )
- conf = try_add_boot( conf, disk, true );
- y2milestone( "do_flexible_disk_conf parts %1", disk["partitions"]:[] );
- y2milestone( "do_flexible_disk_conf conf %1", conf );
- map ret = $[];
- ret["ok"] = false;
- map solutions = $[];
-
- if( size(conf)>0 && size(conf["partitions"]:[])>0 &&
- Storage::IsPartitionable( disk ))
- {
- y2milestone( "do_flexible_disk_conf processing disk %1", dev );
- cur_mode = reuse?`reuse:`free;
- cur_gap = $[];
- map gap = get_gap_info( disk, reuse );
- map tc = add_cylinder_info( conf, gap );
- map sol = get_perfect_list( tc["partitions"]:[], gap );
- if( size(sol)>0 )
- {
- sol["disk"] = eval(disk);
- ret["ok"] = true;
- ret["disk"] = process_partition_data( dev, sol, "" );
- ret["weight"] = sol["weight"]:-1;
- }
- }
- else if( Storage::IsPartitionable( disk ) )
- {
- ret["ok"] = true;
- ret["disk"] = disk;
- }
- y2milestone( "do_flexible_disk_conf ret %1", ret["ok"]:false );
- if( ret["ok"]:false && size(conf)>0 )
- {
- y2milestone( "do_flexible_disk_conf weight %1", ret["weight"]:-2 );
- y2milestone( "do_flexible_disk_conf parts %1", ret["disk","partitions"]:[] );
- }
- return( ret );
- }
-
- define map do_vm_disk_conf( map disk, map boot, string vmkey, string key )
- ``{
- string dev = disk["device"]:"";
- y2milestone( "do_vm_disk_conf dev %1 vmkey %2 key %3 boot %4",
- dev, vmkey, key, boot );
- y2milestone( "do_vm_disk_conf parts %1", disk["partitions"]:[] );
- map conf = $[ "partitions" : [ $[ "id" : 0x8E ] ] ];
- if( size(boot)>0 )
- conf["partitions"] = add( conf["partitions"]:[], boot );
- map ret = $[];
- ret["ok"] = false;
-
- integer fsid = conf["partitions",0,"id"]:0;
- if( Storage::IsPartitionable( disk ))
- {
- y2milestone( "do_vm_disk_conf processing disk %1", dev );
- cur_mode = `free;
- cur_gap = $[];
- map gap = get_gap_info( disk, true );
- y2milestone( "do_vm_disk_conf gap %1", gap );
- y2milestone( "do_vm_disk_conf conf %1", conf );
- map tc = add_cylinder_info( conf, gap );
- y2milestone( "do_vm_disk_conf tc %1", tc );
- y2milestone( "do_vm_disk_conf gap %1", gap["gap"]:[] );
- if( size(gap["gap"]:[])>1 )
- {
- gap["gap"] = sort( map a, map b, gap["gap"]:[],
- ``{
- if( a["extended"]:false==b["extended"]:false )
- return( a["start"]:0<b["start"]:0 );
- else
- return( !a["extended"]:false );
- });
- y2milestone( "do_vm_disk_conf gap %1", gap["gap"]:[] );
- }
- boolean ok = size(boot)==0;
- if( !ok )
- {
- integer gstart = -1;
- map bo = find( map p, (list<map>)tc["partitions"]:[],
- ``(p["mount"]:""==boot["mount"]:"") );
- y2milestone( "do_vm_disk_conf boot %1", bo );
- integer cyl_num = bo["cylinders"]:1;
- y2milestone( "do_vm_disk_conf boot cyl %1", cyl_num );
- gap["gap"] = maplist( map g, gap["gap"]:[],
- ``{
- if( !g["exists"]:false && !ok && g["cylinders"]:0>=cyl_num &&
- ((g["extended"]:false && size(gap["ext_pnr"]:[])>1)||
- (!g["extended"]:false && size(gap["free_pnr"]:[])>1)))
- {
- ok = true;
- gstart = g["start"]:-1;
- string key = g["extended"]:false ? "ext_pnr" : "free_pnr";
- g["added"] = [ [ 1, gap[key,0]:0, cyl_num ] ];
- g["cylinders"] = g["cylinders"]:0-cyl_num;
- gap[key] = remove( gap[key]:[], 0 );
- if( g["cylinders"]:0 > 0 )
- {
- g["added"] = add( g["added"]:[],
- [ 0, gap[key,0]:0, g["cylinders"]:0 ] );
- g["cylinders"] = 0;
- gap[key] = remove( gap[key]:[], 0 );
- }
- }
- return( g );
- });
- if( !ok )
- {
- gap["gap"] = maplist( map g, gap["gap"]:[],
- ``{
- if( !g["exists"]:false && !ok && g["cylinders"]:0>=cyl_num &&
- ((g["extended"]:false && size(gap["ext_pnr"]:[])>0)||
- (!g["extended"]:false && size(gap["free_pnr"]:[])>0)))
- {
- ok = true;
- gstart = g["start"]:-1;
- string key = g["extended"]:false ? "ext_pnr" : "free_pnr";
- g["added"] = [ [ 1, gap[key,0]:0, cyl_num ] ];
- g["cylinders"] = g["cylinders"]:0-cyl_num;
- gap[key] = remove( gap[key]:[], 0 );
- }
- return( g );
- });
- }
- if( ok && size(vmkey)>0 )
- {
- gap["gap"] = filter( map g, gap["gap"]:[],
- ``(g["start"]:0==gstart));
- }
- y2milestone( "do_vm_disk_conf gap %1", gap["gap"]:[] );
- }
- else if( size(vmkey)>0 )
- gap = $[];
- map sol = $[];
- sol["solution"] = gap;
- sol["partitions"] = conf["partitions"]:[];
- sol["disk"] = disk;
- ret["ok"] = ok;
- ret["weight"] = 0;
- if( ok && size(vmkey)==0 )
- {
- if( size(gap["ext_reg"]:[])>0 )
- {
- integer ext_end = gap["ext_reg",0]:0 + gap["ext_reg",1]:0 - 1;
- map aext = find( map g, gap["gap"]:[],
- ``(size(g["added"]:[])==0 &&
- !g["exists"]:false &&
- g["start"]:0>=ext_end &&
- g["start"]:0-ext_end<=1));
- y2milestone( "do_vm_disk_conf ee:%1 ae:%2", ext_end, aext );
- if( aext!=nil )
- {
- gap["resize_ext"] = aext["end"]:0;
- gap["gap"] = filter( map g, gap["gap"]:[],
- ``(g["start"]:0!=aext["start"]:0));
- aext = find( map g, gap["gap"]:[],
- ``(!g["exists"]:false && g["extended"]:false &&
- g["end"]:0==ext_end));
- y2milestone( "do_vm_disk_conf aext %1", aext );
- if( aext != nil )
- {
- gap["gap"] = maplist( map g, gap["gap"]:[],
- ``{
- if( g["end"]:0==aext["end"]:0 )
- {
- g["cylinders"] = g["cylinders"]:0 +
- gap["resize_ext"]:0 -
- g["end"]:0;
- g["end"] = gap["resize_ext"]:0;
- }
- return( g );
- });
- }
- else
- {
- map a = $[ "extended" : true,
- "start" : gap["ext_reg",0]:0+gap["ext_reg",1]:0,
- "end" : gap["resize_ext"]:0 ];
- a["cylinders"] = a["end"]:0 - a["start"]:0 + 1;
- y2milestone("do_vm_disk_conf add gap %1", a );
- y2milestone("do_vm_disk_conf add gap %1", gap["gap"]:[] );
- gap["gap"] = add( gap["gap"]:[], a );
- y2milestone("do_vm_disk_conf add gap %1", gap["gap"]:[] );
- }
- }
- y2milestone( "do_vm_disk_conf aext gap %1", gap );
- }
- gap["gap"] = maplist( map g, gap["gap"]:[],
- ``{
- if( g["exists"]:false )
- {
- map acur = find( map gg, gap["gap"]:[],
- ``(size(gg["added"]:[])==0 &&
- !gg["exists"]:false &&
- gg["extended"]:false==g["extended"]:false &&
- gg["start"]:0>=g["end"]:0 &&
- gg["start"]:0-g["end"]:0<=1));
- y2milestone( "do_vm_disk_conf ee:%1 ae:%2",
- g["end"]:0, acur );
- if( acur!=nil )
- {
- g["resize"] = acur["end"]:0;
- g["fsid"] = fsid;
- }
- }
- return( g );
- });
- list<integer> sl = maplist( map g, gap["gap"]:[],
- ``(g["resize"]:-1));
- y2milestone( "do_vm_disk_conf sl %1", sl );
- gap["gap"] = filter( map g, gap["gap"]:[],
- ``(!contains(sl,g["end"]:0)));
- gap["gap"] = sort( map a, map b, gap["gap"]:[],
- ``{
- return( a["cylinders"]:0>b["cylinders"]:0 );
- });
- y2milestone( "do_vm_disk_conf sorted gap %1", gap["gap"]:[] );
- gap["gap"] = maplist( map g, gap["gap"]:[],
- ``{
- if( !g["exists"]:false && g["cylinders"]:0>0 &&
- ((g["extended"]:false && size(gap["ext_pnr"]:[])>0)||
- (!g["extended"]:false && size(gap["free_pnr"]:[])>0)))
- {
- string key = g["extended"]:false ? "ext_pnr" : "free_pnr";
- g["added"] = add( g["added"]:[],
- [ 0, gap[key,0]:0, g["cylinders"]:0 ]);
- g["cylinders"] = 0;
- gap[key] = remove( gap[key]:[], 0 );
- }
- return( g );
- });
- gap["gap"] = maplist( map g, gap["gap"]:[],
- ``{
- if( g["exists"]:false && fsid!=0 && g["fsid"]:0!=fsid )
- {
- g["fsid"] = fsid;
- }
- return( g );
- });
- y2milestone( "do_vm_disk_conf end gap %1", gap["gap"]:[] );
- sol["solution"] = gap;
- }
- ret["disk"] = process_partition_data( dev, sol, key );
- }
- y2milestone( "do_vm_disk_conf ret %1", ret["ok"]:false );
- if( ret["ok"]:false )
- {
- y2milestone( "do_vm_disk_conf weight %1", ret["weight"]:-2 );
- y2milestone( "do_vm_disk_conf parts %1", ret["disk","partitions"]:[] );
- }
- return( ret );
- }
-
- define list<string> restrict_disk_names( list<string> disks )
- {
- list<string> ddev = disks;
- list<string> d1 = filter( string s, ddev, ``(search(s,"/dev/hd")==0));
- ddev = filter( string s, ddev, ``(search(s,"/dev/hd")!=0));
- if( size(d1)>2 )
- {
- integer count=1;
- d1 = maplist( string s, d1,
- ``{
- return( (count<=2)?s:"" );
- count=count+1;
- });
- d1 = filter( string s, d1, ``(size(s)>0));
- }
- d1 = (list<string>)merge( d1, filter( string s, ddev,
- ``(search(s,"/dev/sd")==0)));
- ddev = filter( string s, ddev, ``(search(s,"/dev/sd")!=0));
- ddev = (list<string>)merge( d1, ddev );
- if( size(ddev)>4 )
- {
- integer count=1;
- ddev = maplist( string s, ddev,
- ``{
- return( (count<=4)?s:"" );
- count=count+1;
- });
- ddev = filter( string s, ddev, ``(size(s)>0));
- }
- y2milestone( "restrict_disk_names: ret %1", ddev );
- return( ddev );
- }
-
- define map do_pflex( map<string,map> target, map conf )
- {
- map ret = $[];
- ret["ok"] = false;
- list<map> solutions = [];
- cur_mode = `free;
- if( size(conf)>0 )
- {
- list<string> ddev = maplist( string k, map e,
- filter( string l, map f, target,
- ``(!ignore_disk(l,f,false))), ``(k));
- ddev = sort( ddev );
- y2milestone( "do_pflex ddev %1", ddev );
- map tc = $[];
- map<integer,any> dtmp = $[];
- foreach( map p, conf["partitions"]:[],
- ``{
- integer dprio = p["disk"]:0;
- if( haskey( dtmp, dprio ))
- {
- dtmp[dprio] = add( dtmp[dprio]:[], p );
- }
- else
- {
- dtmp[dprio] = [ p ];
- }
- });
- y2milestone( "do_pflex dlist %1", dtmp );
- list dlist = maplist( integer k, any e, dtmp, ``(e) );
- y2milestone( "do_pflex dlist %1", dlist );
- if( size(dlist)>size(ddev) )
- {
- integer idx = size(ddev);
- while( idx<size(dlist) )
- {
- dlist[size(ddev)-1] = union( dlist[size(ddev)-1]:[],
- dlist[idx]:[] );
- idx = idx+1;
- }
- while( size(dlist)>size(ddev) )
- {
- dlist = remove( dlist, size(ddev) );
- }
- y2milestone( "do_pflex dlist %1", dlist );
- }
- list save_dlist = (list) eval(dlist);
- repeat
- {
- integer count = 0;
- repeat
- {
- list<string> td = eval(ddev);
- integer idx = 0;
- y2milestone( "do_pflex start while count %1", count );
- while( idx<size(dlist) && count<size(dlist) )
- {
- y2milestone( "do_pflex in while idx %1", idx );
- tc = (map) eval(conf);
- tc["partitions"] = eval( dlist[idx]:[] );
- map md = find_matching_disk( td, target, tc );
- y2milestone( "do_pflex size(md) %1", size(md) );
- if( size(md)>0 )
- {
- solutions = add( solutions, md );
- td = filter( string e, td, ``(e!=md["device"]:""));
- y2milestone( "do_pflex new td %1", td );
- idx = idx+1;
- }
- else
- {
- y2milestone( "do_pflex no solution" );
- idx = size(dlist);
- td = eval(ddev);
- solutions = [];
- count = count + 1;
- if( size(dlist)>1 )
- {
- list tfi = dlist[0]:[];
- dlist = remove( dlist, 0 );
- dlist = add( dlist, tfi );
- y2milestone( "do_pflex new rot dlist %1", dlist );
- }
- }
- }
- }
- until( size(solutions)>0 || count>=size(dlist) );
- if( size(solutions)==0 && size(dlist)>1 )
- {
- dlist = (list) eval(save_dlist);
- dlist[size(dlist)-2] = union( dlist[size(dlist)-2]:[],
- dlist[size(dlist)-1]:[] );
- dlist = remove( dlist, size(dlist)-1 );
- y2milestone( "do_pflex new truncated dlist %1",
- dlist );
- save_dlist = (list)eval(dlist);
- }
- }
- until( size(solutions)>0 || size(dlist)<=1 );
- if( size(solutions)==0 &&
- (size(conf["keep_partition_fsys"]:[])>0 ||
- size(conf["keep_partition_id"]:[])>0 ||
- size(conf["keep_partition_num"]:[])>0 ||
- !conf["prefer_remove"]:false))
- {
- y2milestone( "do_pflex desperate mode" );
- tc = (map) eval(conf);
- cur_mode = `desparate;
- tc["keep_partition_fsys"] = [];
- tc["keep_partition_id"] = [];
- tc["keep_partition_num"] = [];
- tc["prefer_remove"] = true;
- map md = find_matching_disk( ddev, target, tc );
- if( size(md)>0 )
- {
- solutions = add( solutions, md );
- }
- }
- if( size(solutions)>0 )
- {
- foreach( map e, solutions,
- ``{
- string disk = e["device"]:"";
- target[disk] = process_partition_data( disk, e, "" );
- y2milestone( "do_pflex solution disk %1 %2",
- disk, target[disk]:$[] );
- });
- ret["ok"] = true;
- target = Storage::SpecialBootHandling( target );
- ret["target"] = Storage::DeleteDestroyedLvmVgs( target );
- }
- }
- return( ret );
- }
-
-
- define map do_proposal_flexible( map<string,map> target )
- ``{
- map conf = $[];
- if( ProductFeatures::GetBooleanFeature( "partitioning",
- "use_flexible_partitioning"))
- conf = read_partition_xml_config();
- else
- conf = read_partition_config( pinfo_name() );
-
- return( do_pflex( target, conf ) );
- }
-
- 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]:$[];
- y2milestone( "find_matching_disk processing disk %1", k );
- y2milestone( "find_matching_disk parts %1", conf["partitions"]:[] );
- map tc = try_add_boot( conf, e, false );
- if( cur_mode != `desparate )
- cur_mode = `free;
- if( !tc["prefer_remove"]:false )
- {
- map gap = get_gap_info( e, 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, 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( "find_matching_disk solution reuse existing" );
- solutions[k] = eval(l);
- solutions[k,"disk"] = eval(e);
- }
- }
- cur_mode = `resize;
- map rw = try_resize_windows( e );
- if( find( map p, rw["partitions"]:[], ``(p["resize"]:false))!=nil )
- {
- egap = get_gap_info( rw, 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( "find_matching_disk solution resizing windows" );
- solutions[k] = eval(l);
- solutions[k,"disk"] = eval(rw);
- }
- }
- }
- else
- {
- map rp = remove_possible_partitions( e, tc );
- map gap = get_gap_info( rp, 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( "find_matching_disk 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( "find_matching_disk sorted disks %1", disks );
- ret = solutions[disks[0]:""]:$[];
- ret["device"] = disks[0]:"";
- }
- return( ret );
- }
-
- define map process_partition_data( string dev, map solution, string vgname )
- ``{
- map disk = solution["disk"]:$[];
- list<map> partitions = [];
- string value = "";
- 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() && !need_boot(disk) )
- {
- 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( "process_partition_data 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);
- }
- pindex = pindex+1;
- });
- index = index + 1;
- });
- }
- if( solution["solution","resize_ext"]:0>0 )
- {
- disk["partitions"] = maplist( map p, disk["partitions"]:[],
- ``{
- if( p["type"]:`unknown==`extended )
- {
- p["resize"] = true;
- p["ignore_fs"] = true;
- p["region",1] = solution["solution","resize_ext"]:0 -
- p["region",0]:0 + 1;
- p["size_k"] = p["region",1]:0 * disk["cyl_size"]:0 / 1024;
- y2milestone( "process_partition_data resize ext %1", p );
- }
- return( p );
- });
- }
- foreach( map e, solution["solution","gap"]:[],
- ``{
- y2milestone( "process_partition_data e %1", e );
- 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["nr"]:0 == e["added",0,1]:0 )
- {
- y2milestone( "process_partition_data reuse part %1", p );
- p["format"] = true;
- p["mount"] = mount;
- p["used_fs"] =
- solution["partitions",pindex,"fsys"]:Partitions::DefaultFs();
- value = solution["partitions",pindex,"fstopt"]:"";
- if( size(value)>0 )
- {
- p["fstopt"] = value;
- }
- else
- {
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- }
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- value = solution["partitions",pindex,"fopt"]:"";
- if( size(value)>0 )
- {
- p["format_opt"] = value;
- }
- value = solution["partitions",pindex,"label"]:"";
- if( size(value)>0 )
- {
- p["label"] = value;
- }
- if( p["fsid"]:0 != fsid )
- {
- p["change_fsid"] = true;
- p["ori_fsid"] = p["fsid"]:0;
- p["fsid"] = fsid;
- }
- if( size(mount)==0 && size(vgname)>0 &&
- p["type"]:`unknown!=`extended )
- p["vg"] = vgname;
- disk["partitions",index] = p;
- y2milestone( "process_partition_data reuse auto part %1", p );
- }
- else if( (size(vgname)>0||e["resize"]:0>0) &&
- p["nr"]:0 == e["nr"]:0 )
- {
- if( e["fsid"]:0!=0 && e["fsid"]:0!=p["fsid"]:0 )
- {
- p["change_fsid"] = true;
- p["ori_fsid"] = p["fsid"]:0;
- p["fsid"] = e["fsid"]:0;
- }
- if( e["resize"]:0>0 )
- {
- p["resize"] = true;
- p["ignore_fs"] = true;
- p["region",1] = e["resize"]:0 - p["region",0]:0 + 1;
- p["size_k"] = p["region",1]:0 *
- disk["cyl_size"]:0 / 1024;
- }
- if( size(vgname)>0 )
- p["vg"] = vgname;
- disk["partitions",index] = p;
- y2milestone( "process_partition_data resize part %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 )
- {
- while( e["added",0,1]:(disk["max_primary"]:4+1) <=
- disk["max_primary"]:4 )
- {
- integer pindex = e["added",0,0]:0;
- string mount = solution["partitions",pindex,"mount"]:"";
- integer fsid = Partitions::fsid_native;
- part["format"] = true;
- if( mount == "swap" )
- {
- fsid = Partitions::fsid_swap;
- }
- part["create"] = true;
- part["nr"] = e["created"]:0;
- part["device"] = Storage::GetDeviceName( dev, part["nr"]:-1 );
- part["region"] = region;
- part["region",1] = e["added",0,2]:0;
- region[0] = region[0]:0 + part["region",1]:0;
- region[1] = region[1]:0 - part["region",1]:0;
- part["type"] = `primary;
- if( solution["partitions",pindex,"id"]:0 != 0 )
- {
- fsid = solution["partitions",pindex,"id"]:0;
- if( !haskey( solution["partitions",pindex]:$[], "fsys" ))
- {
- part["format"] = false;
- }
- }
- part["size_k"] = part["region",1]:0 * disk["cyl_size"]:0 / 1024;
- part["mount"] = mount;
- part["used_fs"] =
- solution["partitions",pindex,"fsys"]:Partitions::DefaultFs();
- value = solution["partitions",pindex,"fstopt"]:"";
- if( size(value)>0 )
- {
- part["fstopt"] = value;
- }
- else
- {
- part["fstopt"] = FileSystems::DefaultFstabOptions( part );
- }
- part["fs_options"] = FileSystems::DefaultFormatOptions( part );
- value = solution["partitions",pindex,"fopt"]:"";
- if( size(value)>0 )
- {
- part["format_opt"] = value;
- }
- value = solution["partitions",pindex,"label"]:"";
- if( size(value)>0 )
- {
- part["label"] = value;
- }
- part["fsid"] = fsid;
- part["fstype"] = Partitions::FsIdToString( fsid );
- if( size(mount)==0 && size(vgname)>0 )
- part["vg"] = vgname;
- y2milestone( "process_partition_data auto partition %1", part );
- partitions = add( partitions, part );
- e["created"] = e["added",0,1]:0;
- e["added"] = remove( e["added"]:[], 0 );
- part = $[];
- }
- 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 );
- part["size_k"] = region[1]:0 * disk["cyl_size"]:0 / 1024;
- y2milestone( "process_partition_data 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"] = true;
- if( mount == "swap" )
- {
- fsid = Partitions::fsid_swap;
- }
- if( solution["partitions",pindex,"id"]:0 != 0 )
- {
- fsid = solution["partitions",pindex,"id"]:0;
- if( !haskey( solution["partitions",pindex]:$[], "fsys" ))
- {
- part["format"] = false;
- }
- y2milestone( "process_partition_data 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["size_k"] = region[1]:0 * disk["cyl_size"]:0 / 1024;
- part["type"] = `primary;
- if( e["extended"]:false )
- {
- part["type"] = `logical;
- }
- part["mount"] = mount;
- part["used_fs"] =
- solution["partitions",pindex,"fsys"]:Partitions::DefaultFs();
- value = solution["partitions",pindex,"fstopt"]:"";
- if( size(value)>0 )
- {
- part["fstopt"] = value;
- }
- else
- {
- part["fstopt"] = FileSystems::DefaultFstabOptions( part );
- }
- part["fs_options"] = FileSystems::DefaultFormatOptions( part );
- value = solution["partitions",pindex,"fopt"]:"";
- if( size(value)>0 )
- {
- part["format_opt"] = value;
- }
- value = solution["partitions",pindex,"label"]:"";
- if( size(value)>0 )
- {
- part["label"] = value;
- }
- part["fsid"] = fsid;
- part["fstype"] = Partitions::FsIdToString( fsid );
- if( size(mount)==0 && size(vgname)>0 )
- part["vg"] = vgname;
- y2milestone( "process_partition_data 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( "process_partition_data disk %1", disk );
- return( disk );
- }
-
- define map add_cylinder_info( map conf, map gap )
- ``{
- integer cyl_size = gap["cyl_size"]:1;
- conf["partitions"] =
- sort( map a, map b, conf["partitions"]:[],
- ``({
- if( a["primary"]:false != b["primary"]:false )
- return( true );
- else 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( "add_cylinder_info 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;
- if( p["cylinders"]:0 == 0 )
- {
- p["cylinders"] = 1;
- }
- return( p );
- });
- y2milestone( "add_cylinder_info sum %1", sum );
- y2milestone( "add_cylinder_info 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["maxsize"]:0 > 0 )
- {
- integer cyl = (p["maxsize"]:0+cyl_size-1) / cyl_size;
- p["size_max_cyl"] = cyl;
- if( p["want_cyl"]:0 > cyl )
- {
- p["want_cyl"] = cyl;
- }
- }
- return( p );
- });
- y2milestone( "add_cylinder_info parts %1", conf["partitions"]:[] );
- return( conf );
- }
-
- define map get_perfect_list( list ps, map g )
- ``{
- y2milestone( "get_perfect_list ps %1", ps );
- y2milestone( "get_perfect_list gap %1", g );
- if( size(g["gap"]:[])>0 &&
- ((g["extended_possible"]:false &&
- size(g["free_pnr"]:[])>0 &&
- 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);
- 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"]:[]))
- {
- y2milestone( "get_perfect_list 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( "get_perfect_list not creating extended" );
- 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( "get_perfect_list ret weight %1", ret["weight"]:-1000000 );
- y2milestone( "get_perfect_list ret solution %1", ret["solution","gap"]:[] );
- return( ret );
- }
-
- define void add_part_recursive( list ps, map g )
- ``{
- y2milestone( "add_part_recursive pindex %1", g["procpart"]:0 );
- y2milestone( "add_part_recursive ps %1", ps );
- y2milestone( "add_part_recursive gap %1", g );
- map lg = (map) eval(g);
- integer gindex = 0;
- integer pindex = lg["procpart"]:0;
- map part = ps[pindex]:$[];
- lg["procpart"] = pindex + 1;
- y2milestone( "add_part_recursive p %1", part );
- foreach( map e, lg["gap"]:[],
- ``{
- y2milestone( "add_part_recursive e %1", e );
- boolean max_cyl_ok = !haskey( part, "max_cyl" ) ||
- part["max_cyl"]:0 >= e["end"]:0;
- if( !max_cyl_ok )
- {
- integer cyl = 0;
- foreach( list a, lg["gap",gindex,"added"]:[],
- ``{
- cyl = cyl + ps[a[0]:0,"cylinders"]:0;
- });
- cyl = cyl + part["cylinders"]:0;
- y2milestone( "max_cyl_ok cyl %1", cyl );
- max_cyl_ok = e["start"]:0 + cyl <= part["max_cyl"]:0;
- }
- y2milestone( "add_part_recursive max_cyl_ok %1", max_cyl_ok );
- if( max_cyl_ok && part["cylinders"]:0 <= e["cylinders"]:0 &&
- ((!e["extended"]:false && size(lg["free_pnr"]:[])>0) ||
- (part["primary"]:false && e["created"]:false && e["extended"]:false && size(lg["free_pnr"]:[])>0) ||
- (!part["primary"]:false && e["extended"]:false && size(lg["ext_pnr"]:[])>0)))
- {
- map llg = (map) eval(lg);
- if( e["exists"]:false )
- {
- llg["gap",gindex,"cylinders"] = 0;
- }
- else
- {
- llg["gap",gindex,"cylinders"] =
- llg["gap",gindex,"cylinders"]:0 - part["cylinders"]:0;
- }
- list addl = [ pindex ];
- if( e["extended"]:false && !part["primary"]:false )
- {
- addl = add( addl, llg["ext_pnr",0]:5 );
- llg["ext_pnr"] = remove( llg["ext_pnr"]:[0], 0 );
- }
- else
- {
- addl = add( addl, llg["free_pnr",0]:1 );
- llg["free_pnr"] = remove( llg["free_pnr"]:[0], 0 );
- }
- llg["gap",gindex,"added"] =
- add( llg["gap",gindex,"added"]:[], addl );
- if( pindex+1 < size(ps) )
- {
- add_part_recursive( ps, llg );
- }
- else
- {
- map ng = normalize_gaps(ps, llg);
- integer val = do_weighting( ps, ng );
- y2milestone( "add_part_recursive 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;
- });
- };
-
- 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( "normalize_gaps e %1", e );
- if( e["exists"]:false )
- {
- if( size(e["added"]:[])>0 && size(e["added",0]:[])==2 )
- {
- g["gap",gindex,"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( "normalize_gaps 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( "normalize_gaps 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( "normalize_gaps 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( "normalize_gaps satisfy p %1 cyl %2", p,
- e["cylinders"]:0 );
- }
- pindex = pindex+1;
- });
- y2milestone( "normalize_gaps 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( "normalize_gaps 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( "normalize_gaps close small gap 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 )
- {
- list<integer> weight = [];
- weight =
- maplist( list l, e["added"]:[],
- ``((ps[l[0]:0,"increasable"]:false) ? 1 : 0));
- y2milestone( "normalize_gaps w %1", weight );
- 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;
- e["cylinders"] = g["gap",gindex,"cylinders"]:0;
- y2milestone( "normalize_gaps increase increasable 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["extended"]:false && e["created"]:0 > 0 &&
- size(e["added"]:[])==1 && e["cylinders"]:0==0 )
- {
- g["gap",gindex,"extended"] = false;
- g["gap",gindex,"added",0,1] = e["created"]:0;
- y2milestone( "normalize_gaps changed extended %1",
- g["gap",gindex]:$[] );
- }
- gindex = gindex + 1;
- });
- gindex = 0;
- map sort_map = $[ "/boot" : 0, "/boot/efi" : 0, "swap" : 1,
- "/" : 5, "/home" :6 ];
- foreach( map e, g["gap"]:[],
- ``{
- if( !e["exists"]:false && size(e["added"]:[])>1 )
- {
- y2milestone( "normalize_gaps old added %1", e["added"]:[] );
- list nums = maplist( list l, e["added"]:[], ``(l[1]:-1));
- y2milestone( "normalize_gaps old nums %1", nums );
- list sdd = sort( list a, list b, e["added"]:[],
- ``({
- integer ai = a[0]:0;
- integer bi = b[0]:0;
- if( ps[ai,"primary"]:false != ps[bi,"primary"]:false )
- return( ps[ai,"primary"]:false );
- else if( ps[ai,"max_cyl"]:big_cyl != ps[bi,"max_cyl"]:big_cyl )
- return( ps[ai,"max_cyl"]:big_cyl < ps[bi,"max_cyl"]:big_cyl );
- else
- return( sort_map[ps[ai,"mount"]:""]:3 < sort_map[ps[bi,"mount"]:""]:3);
- }));
- integer idx = 0;
- foreach( list e, (list<list>)sdd,
- ``{
- sdd[idx,1] = nums[idx]:0;
- idx = idx+1;
- });
- g["gap",gindex,"added"] = sdd;
- y2milestone( "normalize_gaps sort added %1",
- g["gap",gindex,"added"]:[] );
- }
- gindex = gindex + 1;
- });
- y2milestone( "normalize_gaps gap %1", g );
- return( g );
- };
-
- 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;
- integer scount = 0;
- y2milestone( "distribute_space rest %1 weights %2 added %3", rest,
- weights, added );
- integer loopcount=0;
- do
- {
- loopcount = loopcount+1;
- index = 0;
- sum = 0;
- scount = 0;
- foreach( list p, (list<list>)added,
- ``{
- pindex = p[0]:0;
- if( ps[pindex,"size_max_cyl"]:0==0 ||
- ps[pindex,"size_max_cyl"]:0 > p[2]:0)
- {
- sum = sum + weights[index]:0;
- y2milestone( "sum %1 weight %2 pindex %3", sum,
- weights[index]:0, pindex );
- scount = scount+1;
- }
- index = index+1;
- });
- index = 0;
- y2milestone( "distribute_space sum %1 rest %2 scount %3 added %4 lc %5",
- sum, rest, scount, added, loopcount );
- 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,"size_max_cyl"]:0 > p[2]:0) )
- {
- integer diff = ((rest*weights[index]:0) + sum/2) / sum;
- if( ps[pindex,"size_max_cyl"]:0>0 &&
- 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( "distribute_space sum %1 rest %2 diff %3 added %4",
- sum, rest, diff, added[index]:[] );
- }
- index = index+1;
- });
- }
- while( rest>0 && scount>0 && loopcount<3 );
- map ret = $[ "added":added, "diff" : diff_sum ];
- y2milestone( "distribute_space ret %1", ret );
- return( ret );
- }
-
- define integer do_weighting( list ps, map g )
- ``{
- y2milestone( "do_weighting gap %1", g["gap"]:[] );
- integer ret = 0;
- integer index = 0;
- integer diff = 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( "do_weighting after mode ret %1", ret );
- foreach( map e, g["gap"]:[],
- ``{
- y2milestone( "do_weighting e %1", e );
- if( !e["exists"]:false && e["cylinders"]:0 > 0 )
- {
- diff = -5;
- if( e["cylinders"]:0 < g["disk_cyl"]:0/20 )
- {
- diff = diff - 10;
- }
- ret = ret + diff;
- y2milestone( "do_weighting after gaps diff %1 ret %2", diff, ret );
- }
- foreach( list p, e["added"]:[],
- ``{
- index = p[0]:0;
- if( e["exists"]:false && ps[index,"mount"]:""=="swap" &&
- e["swap"]:false )
- {
- diff = 100;
- ret = ret + diff;
- y2milestone( "do_weighting after swap reuse diff %1 ret %2",
- diff, ret );
- }
- if( ps[index,"want_cyl"]:0>0 )
- {
- 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;
- }
- diff = ps[index,"want_cyl"]:0*g["cyl_size"]:1 / (100*1024*1024) -
- normdiff;
- ret = ret + diff;
- y2milestone( "do_weighting after pct parts diff %1 ret %2",
- diff, ret );
- }
- if( ps[index,"size"]:0==0 )
- {
- diff = p[2]:0 * g["cyl_size"]:1 / (50 * 1024 * 1024);
- ret = ret + diff;
- y2milestone( "do_weighting after maximizes parts diff %1 ret %2",
- diff, ret );
- }
- if( ps[index,"size_max_cyl"]:0 > 0 &&
- ps[index,"size_max_cyl"]:0 < p[2]:0 )
- {
- diff = p[2]:0 - ps[index,"size_max_cyl"]:0;
- integer normdiff = diff * 100 / ps[index,"size_max_cyl"]:0;
- ret = ret - normdiff;
- y2milestone( "do_weighting after maximal size diff %1 ret %2",
- -normdiff, ret );
- }
- });
- if( size(e["added"]:[])>0 && e["cylinders"]:0 > 0 )
- {
- integer diff = (e["cylinders"]:0 * g["cyl_size"]:1) / (1024*1024*1024);
- ret = ret - diff;
- y2milestone( "do_weighting after gap size diff %1 ret %2", -diff, ret );
- }
- if( e["extended"]:false )
- ret = ret-1;
- y2milestone( "do_weighting %1", ret );
- });
- y2milestone( "do_weighting ret %1", ret );
- return( ret );
- };
-
- define list<map> try_remove_sole_extended( list<map> parts )
- {
- list<map> ret = parts;
- if( find( map p, ret,
- ``(p["type"]:`unknown==`extended &&
- !p["delete"]:false))!=nil &&
- find( map p, ret,
- ``(p["type"]:`unknown==`logical &&
- !p["delete"]:false))==nil )
- {
- ret = maplist( map p, ret,
- ``{
- if( p["type"]:`unknown == `extended )
- p["delete"] = true;
- return( p );
- });
- y2milestone( "try_remove_sole_extended delete extended p:%1", ret );
- }
- return( ret );
- }
-
- define map remove_possible_partitions( map disk, map conf )
- ``{
- map ret = (map)eval(disk);
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- integer fsid = p["fsid"]:0;
- if( (conf["remove_special_partitions"]:false ||
- !contains( Partitions::do_not_delete, 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 );
- });
- ret["partitions"] = try_remove_sole_extended( ret["partitions"]:[] );
- return( ret );
- };
-
- 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::IsDosWinNtPartition( fsid ) )
- {
- win = p["winfo"]:$[];
- y2milestone( "try_resize_windows win=%1", win );
- if( win != nil && win["ok"]:false && p["size_k"]:0 > 1024*1024 )
- {
- p["winfo"] = win;
- p["resize"] = true;
- p["region",1] = (win["new_size"]:0 + cyl_size - 1) / cyl_size;
- p["win_max_length"] =
- (win["max_win_size"]:0 + cyl_size - 1) / cyl_size;
- y2milestone( "try_resize_windows win part %1", p );
- }
- }
- return( p );
- });
- return( ret );
- };
-
- define list<map> get_gaps( integer start, integer end, list<map> part,
- boolean add_exist_linux )
- ``{
- y2milestone( "get_gaps 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 = $[];
- if( start < s )
- {
- entry["start"] = start;
- entry["end"] = s-1;
- ret = add( ret, eval(entry) );
- }
- if( add_exist_linux && size(p["mount"]:"")==0 &&
- (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 );
- }
- start = e+1;
- });
- if( start < end )
- {
- entry = $[];
- entry["start"] = start;
- entry["end"] = end;
- ret = add( ret, entry );
- }
- y2milestone( "get_gaps ret %1", ret );
- return( ret );
- }
-
-
- define map get_gap_info( map disk, 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<integer> exist_pnr = sort( maplist( map e, plist, ``(e["nr"]:0) ));
- if( disk["label"]:""=="mac" && !contains( exist_pnr, 1 ) )
- {
- exist_pnr = add( exist_pnr, 1 );
- }
- integer max_prim = Partitions::MaxPrimary(disk["label"]:"msdos");
- boolean has_ext = Partitions::HasExtended( disk["label"]:"msdos" );
- if( has_ext )
- {
- map ext = filter( map p, plist,
- ``(p["type"]:`primary == `extended))[0]:$[];
- ret["extended_possible"] = size(ext)==0;
- ret["ext_reg"] = ext["region"]:[];
- if( size(ext)>0 )
- {
- gap = get_gaps( ext["region",0]:0,
- ext["region",0]:0 + ext["region",1]:1-1,
- 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, 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["sum"] = av_size;
- integer max_pnr = max_prim;
- integer pnr = 1;
- list free_pnr = [];
- y2milestone( "get_gap_info 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( !has_ext )
- {
- ext_pnr = [];
- }
- else
- {
- integer maxlog = size(filter( integer i, exist_pnr, ``(i>max_pnr))) + 4;
- ext_pnr = filter( integer i, ext_pnr, ``(i>maxlog));
- }
- ret["ext_pnr"] = ext_pnr;
- ret["gap"] = gap;
- y2milestone( "get_gap_info ret %1", ret );
- return( ret );
- }
-
- /**
- * Read partition data from XML control file
- * @return map flexible propsal map
- */
- define map read_partition_xml_config()
- ``{
-
- map xmlflex = (map)ProductFeatures::GetFeature ("partitioning", "flexible_partitioning");
- y2debug("xml input: %1", xmlflex );
-
- map conf = $[];
- conf["prefer_remove"] = xmlflex["prefer_remove"]:true;
- conf["remove_special_partitions"] =
- xmlflex["remove_special_partitions"]:false;
- conf["keep_partition_id"] = [];
- conf["keep_partition_num"] = [];
- conf["keep_partition_fsys"] = [];
-
- foreach( string key, [ "keep_partition_id", "keep_partition_num"], ``{
- list num = [];
- list<string> nlist = splitstring(xmlflex[key]:"", ",");
- foreach( string n, nlist, ``{ num = union( num, [tointeger(n)] );});
- conf[key] = num;
- });
-
- list fsys = [];
- list<string> nlist = splitstring( xmlflex["keep_partition_fsys"]:"" , "," );
- foreach( string n, nlist,
- ``{
- symbol fs = FileSystems::FsToSymbol(n);
- if( fs != `none )
- {
- fsys = union( fsys, [ fs ] );
- }
- });
- conf["keep_partition_fsys"] = fsys;
- list partitions = [];
- foreach(map p, xmlflex["partitions"]:[],
- ``{
- map partition = $[];
-
- if (p["disk"]:0 != 0)
- {
- partition["disk"] = p["disk"]:0;
- }
- if (p["id"]:0 != 0)
- {
- partition["id"] = p["id"]:0;
- }
-
- if (p["fstopt"]:"" != "")
- {
- partition["fstopt"] = p["fstopt"]:"";
- }
-
- if (p["formatopt"]:"" != "")
- {
- partition["fopt"] = p["formatopt"]:"";
- }
-
- partition["increasable"] = p["increasable"]:false;
-
- if (p["mount"]:"" != "")
- {
- partition["mount"] = p["mount"]:"";
- }
-
- if (p["percent"]:-1 != -1)
- {
- partition["pct"] = p["percent"]:100;
- }
-
- if (p["label"]:"" != "")
- {
- partition["label"] = p["label"]:"";
- }
-
- if (p["maxsize"]:"" != "")
- {
- partition["maxsize"] = kmgt_str_to_byte(p["maxsize"]:"");
- }
-
- if (p["fsys"]:"" != "")
- {
- symbol fs = FileSystems::FsToSymbol(p["fsys"]:"");
- if( fs != `none )
- {
- partition["fsys"] = fs;
- }
- }
-
- if (p["size"]:"" != "")
- {
- string s = p["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["fsys"]:`none == `none )
- {
- partition["fsys"] = Partitions::DefaultBootFs();
- }
- if( partition["id"]:0 == 0 )
- {
- partition["id"] = Partitions::FsidBoot();
- }
- partition["max_cyl"] = Partitions::BootCyl();
- }
- if( partition["size"]:0 == -1 )
- {
- partition["size"] = 0;
- }
-
- y2debug("partition: %1", partition);
- if( size(partition["mount"]:"")>0 || partition["id"]:0 > 0 )
- {
- partitions = add( partitions, partition );
- }
-
-
- });
- conf["partitions"] = partitions;
- if( size(partitions)==0 )
- {
- conf = $[];
- }
- else
- {
- conf["partitions"] = partitions;
- }
- y2milestone( "conf %1", conf );
- return( conf );
-
-
-
- }
-
-
- define map read_partition_config( string fpath )
- ``{
- integer pos = 0;
- string line = "";
- string rex = "";
- map conf = $[];
-
- conf["prefer_remove"] = true;
- conf["remove_special_partitions"] = false;
- conf["keep_partition_id"] = [];
- conf["keep_partition_num"] = [];
- conf["keep_partition_fsys"] = [];
-
- string cstring = (string) SCR::Read( .target.string, fpath );
- list<string> lines = filter( string e, splitstring( cstring, "\n" ), ``(size(e)>0) );
- rex = "[ \t]*#.*";
- y2milestone( "lines %1", lines );
- lines = filter( string e, lines, ``(!regexpmatch( e, "[ \t]*#.*" )));
- y2milestone( "lines %1", lines );
- list fnd = [];
- foreach( string key, [ "PREFER_REMOVE", "REMOVE_SPECIAL_PARTITIONS" ],
- ``{
- rex = "[ \t]*" + key + "[ \t]*=";
- fnd = filter( string e, lines, ``(regexpmatch( e, rex )));
- y2milestone( "rex %1 fnd %2", rex, fnd );
- if( size(fnd)>0 )
- {
- line = deletechars( fnd[size(fnd)-1]:"", "\t " );
- pos = findlastof( line, "=" );
- if( pos > 0 )
- {
- conf[tolower(key)] = tointeger( substring( line, pos+1 ))>0;
- }
- }
- });
- foreach( string key, [ "KEEP_PARTITION_ID", "KEEP_PARTITION_NUM" ],
- ``{
- rex = "[ \t]*" + key + "[ \t]*=";
- y2milestone( "rex %1", rex );
- foreach( string l, filter( string e, lines, ``(regexpmatch( e, rex ))),
- ``{
- y2milestone( "line %1", l );
- line = deletechars( l, "\t " );
- pos = findlastof( line, "=" );
- if( pos > 0 )
- {
- list num = [];
- list<string> nlist = splitstring( substring( line, pos+1 ), "," );
- foreach( string n, nlist, ``{ num = union( num, [tointeger(n)] );});
- conf[tolower(key)] = union( conf[tolower(key)]:[], num );
- }
- });
- });
- list fsys = [];
- rex = "[ \t]*" + "KEEP_PARTITION_FSYS" + "[ \t]*=";
- foreach( string l, filter( string e, lines, ``(regexpmatch( e, rex ))),
- ``{
- y2milestone( "line %1", l );
- line = deletechars( l, "\t " );
- pos = findlastof( line, "=" );
- if( pos > 0 )
- {
- list<string> nlist = splitstring( substring( line, pos+1 ), "," );
- foreach( string n, nlist,
- ``{
- symbol fs = FileSystems::FsToSymbol(n);
- if( fs != `none )
- {
- fsys = union( fsys, [ fs ] );
- }
- });
- }
- });
- conf["keep_partition_fsys"] = fsys;
- list partitions = [];
- map part = $[];
- rex = "[ \t]*" + "PARTITION" + "[ \t][ \t]*";
- foreach( string l, filter( string e, lines, ``(regexpmatch( e, rex ))),
- ``{
- y2milestone( "line %1", l );
- string par = "";
- string key = "";
- integer pos = search( l, "PARTITION" );
- line = substring( l, pos+10 );
- y2milestone( "line %1", line );
- pos = search( line, "=" );
- part = $[];
- while( pos!=nil )
- {
- key = deletechars( substring( line, 0, pos ), " \t" );
- line = substring( line, pos+1 );
- if( substring( line, 0, 1 ) == "\"" )
- {
- line = substring( line, 1 );
- pos = search( line, "\"" );
- par = substring( line, 0, pos );
- line = substring( line, pos+1 );
- }
- else
- {
- pos = findfirstof( line, " \t" );
- if( pos==nil )
- {
- par = line;
- }
- else
- {
- par = substring( line, 0, pos );
- line = substring( line, pos+1 );
- }
- }
- y2debug( "key %1 par \"%2\"", key, par );
- if( key == "id" )
- {
- part[key] = tointeger(par);
- }
- else if( key == "mount" )
- {
- part[key] = par;
- }
- else if( key == "increasable" )
- {
- part["increasable"] = tointeger(par)>0 ? true : false;
- }
- else if( key == "size" )
- {
- if( tolower(par) == "auto" )
- {
- part["size"] = -1;
- }
- else if( tolower(par) == "max" )
- {
- part["size"] = 0;
- }
- else
- {
- part["size"] = kmgt_str_to_byte( par );
- }
- }
- else if( key == "label" )
- {
- part[key] = par;
- }
- else if( key == "maxsize" )
- {
- part[key] = kmgt_str_to_byte( par );
- }
- else if( key == "sizepct" )
- {
- part["pct"] = tointeger(par);
- }
- else if( key == "disk" )
- {
- part[key] = tointeger(par);
- }
- else if( key == "fsys" )
- {
- symbol fs = FileSystems::FsToSymbol(par);
- if( fs != `none )
- {
- part[key] = fs;
- }
- }
- else if( key == "fstopt" )
- {
- part[key] = par;
- }
- else if( key == "formatopt" )
- {
- part["fopt"] = par;
- }
- pos = search( line, "=" );
- }
- y2milestone( "part %1", part );
- if( part["size"]:0 == -1 && part["mount"]:"" == "swap" )
- {
- part["size"] = 1024*1024*Partitions::SwapSizeMb(0);
- }
- if( part["mount"]:"" == Partitions::BootMount() )
- {
- if( part["size"]:0 == -1 )
- {
- part["size"] = Partitions::MinimalNeededBootsize();
- }
- if( part["fsys"]:`none == `none )
- {
- part["fsys"] = Partitions::DefaultBootFs();
- }
- if( part["id"]:0 == 0 )
- {
- part["id"] = Partitions::FsidBoot();
- }
- part["max_cyl"] = Partitions::BootCyl();
- }
- if( part["size"]:0 == -1 )
- {
- part["size"] = 0;
- }
- if( size(part["mount"]:"")>0 || part["id"]:0 > 0 )
- {
- partitions = add( partitions, part );
- }
- });
- conf["partitions"] = partitions;
- if( size(partitions)==0 )
- {
- conf = $[];
- }
- else
- {
- conf["partitions"] = partitions;
- }
- y2milestone( "conf %1", conf );
- return( conf );
- }
-
- map can_swap_reuse( string disk, list<map> partitions, map<string,map> tgmap )
- {
- map ret = $[];
- y2milestone( "can_swap_reuse disk %1 partitions %2", disk, partitions );
- list<map> swaps = filter( map p, partitions,
- ``(p["type"]:`unknown!=`free &&
- !p["delete"]:false &&
- p["detected_fs"]:`unknown==`swap));
- swaps = filter( map p, swaps, ``(Storage::CheckSwapable(p["device"]:"")));
- swaps = sort( map a, map b, swaps, ``(a["size_k"]:0>b["size_k"]:0));
- y2milestone( "can_swap_reuse swaps %1", swaps );
- if( swaps[0,"size_k"]:0 >= 128*1024 )
- {
- ret["partitions"] =
- maplist( map p, partitions,
- ``{
- if( !p["delete"]:false &&
- p["device"]:""==swaps[0,"device"]:"" )
- {
- p["mount"] = "swap";
- if( haskey( p, "vg" ))
- {
- p = remove( p, "vg" );
- if( p["change_fsid"]:false )
- p["fsid"] = p["ori_fsid"]:Partitions::fsid_swap;
- }
- }
- return( p );
- });
- }
- else
- {
- swaps = [];
- map<string,map> tg = filter( string k, map d, tgmap,
- ``(Storage::IsPartitionable(d)));
- if( haskey( tg, disk ))
- tg = remove( tg, disk );
- y2milestone( "can_swap_reuse tg wo %1", tg );
- foreach( string dev, map disk, tg,
- ``{
- list sw = filter( map p, disk["partitions"]:[],
- ``(p["type"]:`unknown!=`extended &&
- !p["delete"]:false &&
- p["detected_fs"]:`unknown==`swap));
- y2milestone( "can_swap_reuse disk %1 sw %2", dev, sw );
- swaps = (list<map>)union( swaps, sw );
- });
- swaps = sort( map a, map b, swaps, ``(a["size_k"]:0>b["size_k"]:0));
- y2milestone( "can_swap_reuse swaps %1", swaps );
- if( swaps[0,"size_k"]:0 >= 256*1024 )
- {
- ret["targets"] = Storage::SetPartitionData( tgmap,
- swaps[0,"device"]:"",
- "mount", "swap" );
- ret["targets"] = Storage::DelPartitionData( ret["targets"]:$[],
- swaps[0,"device"]:"",
- "vg" );
- }
- }
- y2milestone( "can_swap_reuse ret %1", ret );
- return( ret );
- }
-
- list<map> can_boot_reuse( string disk, string label, boolean boot,
- integer max_prim, list<map> partitions )
- {
- list<map> ret = [];
- y2milestone( "can_boot_reuse boot %1", boot );
- if( boot && !Partitions::PrepBoot() )
- {
- y2milestone( "can_boot_reuse disk %1 max_prim %2 label %3 part %4",
- disk, max_prim, label, partitions );
- list<map> pl = [];
- pl = filter( map p, partitions,
- ``(!p["delete"]:false &&
- p["size_k"]:0*1024 >=
- Partitions::MinimalRequiredBootsize()));
- map boot = find( map p, pl,
- ``((p["fsid"]:0 == Partitions::fsid_gpt_boot) ||
- (p["fsid"]:0 == Partitions::FsidBoot() &&
- p["size_k"]:0<500*1024)||
- (p["detected_fs"]:`unknown==`hfs &&
- p["boot"]:false && label=="mac") ||
- (p["fsid"]:0 == Partitions::fsid_prep_chrp_boot &&
- p["nr"]:0 <= max_prim &&
- Partitions::PrepBoot())));
- if( boot != nil )
- {
- ret = maplist( map p, partitions,
- ``{
- if( !p["delete"]:false &&
- p["device"]:""==boot["device"]:"" )
- {
- p["mount"] = Partitions::BootMount();
- p["used_fs"] = Partitions::DefaultBootFs();
- p["format"] = true;
- p["fstopt"] =
- FileSystems::DefaultFstabOptions( p );
- p["fs_options"] =
- FileSystems::DefaultFormatOptions( p );
- }
- return( p );
- });
- }
- y2milestone( "can_boot_reuse ret %1", ret );
- }
- return( ret );
- }
-
- list<map> can_mp_reuse( string mp, integer min, integer max,
- list<map> partitions )
- {
- list<map> ret = [];
- y2milestone( "can_mp_reuse mp %1 min %2 max %3", mp, min, max );
- list<map> pl = [];
- pl = filter( map p, partitions,
- ``(!p["delete"]:false &&
- p["fsid"]:Partitions::fsid_native ==
- Partitions::fsid_native &&
- p["used_by_type"]:`UB_NONE == `UB_NONE &&
- size(p["mount"]:"")==0 &&
- p["size_k"]:0/1024 >= min &&
- (max==0 || p["size_k"]:0/1024 <= max)));
- y2milestone( "can_mp_reuse normal %1", pl );
- if( size(pl)>0 )
- {
- pl = sort( map a, map b, pl, ``(a["size_k"]:0>b["size_k"]:0));
- y2milestone( "can_mp_reuse sorted %1", pl );
- ret = maplist( map p, partitions,
- ``{
- if( !p["delete"]:false &&
- p["device"]:""==pl[0,"device"]:"" )
- {
- p["mount"] = mp;
- p["used_fs"] = Partitions::DefaultFs();
- p["format"] = true;
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- p["fs_options"] =
- FileSystems::DefaultFormatOptions( p );
- }
- return( p );
- });
- }
- y2milestone( "can_mp_reuse ret %1", ret );
- return( ret );
- }
-
- integer get_avail_size_mb( list<map> parts )
- {
- integer ret = 0;
- foreach( map pp, filter( map p, parts, ``(p["delete"]:false &&
- p["type"]:`unknown!=`extended)),
- ``{
- ret = ret + pp["size_k"]:0/1024;
- });
- y2milestone( "get_avail_size_mb ret %1", ret );
- return( ret );
- }
-
- list get_swap_sizes( integer space )
- {
- list l = [ Partitions::SwapSizeMb(0), Partitions::SwapSizeMb(space) ];
- y2milestone( "get_swap_sizes space %1 ret %2", space, l );
- return( l );
- }
-
- list<map> get_proposal( boolean have_swap, map disk )
- {
- list<map> ret = [];
- y2milestone( "get_proposal have_swap:%1 disk %2", have_swap, disk );
- map root = $[ "mount" : "/", "increasable" : true,
- "fsys" : Partitions::DefaultFs(), "size" : 0 ];
- map opts = Storage::GetControlCfg();
- map conf = $[ "partitions" : [] ];
- list swap_sizes = [];
- integer avail_size = get_avail_size_mb(disk["partitions"]:[]);
- if( !have_swap )
- {
- swap_sizes = get_swap_sizes( avail_size );
- map swap = $[ "mount" : "swap", "increasable" : true, "fsys" : `swap,
- "maxsize" : 2*1024*1024*1024,
- "size" : swap_sizes[0]:256*1024*1024 ];
- conf["partitions"] = add( conf["partitions"]:[], swap );
- }
- conf["partitions"] = add( conf["partitions"]:[], root );
- map old_root = $[];
- if( Storage::ProposalHome() && opts["home_limit"]:0 < avail_size )
- {
- map home = $[ "mount" : "/home", "increasable" : true,
- "fsys" : Partitions::DefaultFs(), "size" : 512*1024*1024,
- "pct" : 100-opts["root_percent"]:40 ];
- conf["partitions"] = maplist( map p, conf["partitions"]:[],
- ``{
- if( p["mount"]:""=="/" )
- {
- old_root = p;
- p["pct"] = opts["root_percent"]:40;
- p["maxsize"] = opts["root_max"]:0*1024*1024;
- p["size"] = opts["root_base"]:0*1024*1024;
- }
- return( p );
- });
- conf["partitions"] = add( conf["partitions"]:[], home );
- }
- map ps1 = do_flexible_disk_conf( disk, conf, false, false );
- if( size(old_root)>0 && !ps1["ok"]:false )
- {
- conf["partitions"] =
- filter( map p, conf["partitions"]:[],
- ``(p["mount"]:""!="/home" && p["mount"]:""!="/"));
- conf["partitions"] = add( conf["partitions"]:[], old_root );
- ps1 = do_flexible_disk_conf( disk, conf, false, false );
- }
- if( !have_swap )
- {
- integer diff = swap_sizes[0]:256 - swap_sizes[1]:256;
- if( diff<0 )
- diff = -diff;
- y2milestone( "get_proposal diff:%1 ps1 ok:%2", diff, ps1["ok"]:false );
- if( (!ps1["ok"]:false && diff>0) || diff>100 )
- {
- conf["partitions",0,"size"] = swap_sizes[1]:256*1024*1024;
- map ps2 = do_flexible_disk_conf( disk, conf, false, false );
- y2milestone( "get_proposal ps2 ok:%1", ps2["ok"]:false );
- if( ps2["ok"]:false )
- {
- map rp1 = find( map p, ps1["disk","partitions"]:[],
- ``(!p["delete"]:false && p["mount"]:""=="/"));
- map rp2 = find( map p, ps2["disk","partitions"]:[],
- ``(!p["delete"]:false && p["mount"]:""=="/"));
- y2milestone( "get_proposal rp1:%1", rp1 );
- y2milestone( "get_proposal rp2:%1", rp2 );
- if( rp1==nil || (rp2!=nil && rp2["size_k"]:0>rp1["size_k"]:0 ))
- ps1 = ps2;
- }
- }
- }
- if( ps1["ok"]:false )
- ret = ps1["disk","partitions"]:[];
- y2milestone( "get_proposal ret:%1", ret );
- return( ret );
- }
-
- integer get_usable_size_mb( map disk, boolean reuse_linux )
- {
- integer ret = 0;
- integer cyl_size = disk["cyl_size"]:0;
- integer disk_cyl = disk["cyl_count"]:0;
- list<map> partitions = filter( map p, disk["partitions"]:[],
- ``(!p["create"]:false));
- partitions = sort( map p1, map p2, partitions,
- ``(p1["region",0]:0 < p2["region",0]:0));
- integer last_end = 0;
- foreach( map p, partitions,
- ``{
- if( p["region",0]:0>last_end )
- ret = ret + (p["region",0]:0-last_end) * cyl_size;
- if( p["type"]:`unknown!=`extended &&
- (p["delete"]:false || (reuse_linux && p["linux"]:false)))
- ret = ret + p["size_k"]:0 * 1024;
- last_end = p["region",0]:0;
- if( p["type"]:`unknown != `extended )
- last_end = last_end + p["region",1]:0;
- });
- if( last_end < disk_cyl )
- ret = ret + (disk_cyl-last_end) * cyl_size;
- ret = ret / (1024*1024);
- return( ret );
- }
-
- integer get_mb_sol( map sol, string mp )
- {
- map pa = find( map p, sol["disk","partitions"]:[], ``(p["mount"]:""==mp));
- y2milestone( "get_mb_sol pa %1", pa );
- integer ret = pa!=nil ? pa["size_k"]:0/1024 : 0;
- y2milestone( "get_mb_sol ret %1", ret );
- return( ret );
- }
-
- integer get_vm_sol( map sol )
- {
- integer ret = 0;
- foreach( map p, sol["disk","partitions"]:[],
- ``{
- if( !p["delete"]:false && (size(p["mount"]:"")>0 || size(p["vg"]:"")>0))
- ret = ret + p["size_k"]:0/1024;
- });
- y2milestone( "get_vm_sol ret %1", ret );
- return( ret );
- }
-
- list<map> special_boot_proposal_prepare( list<map> partitions )
- {
- list<map> ret = partitions;
- if( Partitions::PrepBoot() )
- {
- ret = maplist( map p, partitions,
- ``{
- if( size(p["mount"]:"")==0 &&
- (p["fsid"]:0 == 0x06 || p["fsid"]:0 == 0x41) )
- p["delete"] = true;
- return( p );
- });
- y2milestone( "special_boot_proposal_prepare part:%1", partitions );
- y2milestone( "special_boot_proposal_prepare ret:%1", ret );
- }
- return( ret );
- }
-
- map<string,map> prepare_part_lists( list<string> ddev, map<string,map> tg )
- {
- list linux_pid = [ Partitions::fsid_native, Partitions::fsid_swap,
- Partitions::fsid_lvm, Partitions::fsid_raid ];
- foreach( string s, ddev,
- ``{
- tg[s,"partitions"] =
- maplist( map p, tg[s,"partitions"]:[],
- ``{
- if( contains( linux_pid, p["fsid"]:0 ) ||
- (p["fsid"]:0 == Partitions::fsid_gpt_boot) ||
- (p["fsid"]:0 == Partitions::FsidBoot() &&
- p["size_k"]:0<500*1024)||
- (Partitions::PrepBoot() &&
- (p["fsid"]:0 == Partitions::fsid_prep_chrp_boot||
- p["fsid"]:0 == 0x06)))
- p["linux"] = true;
- else
- p["linux"] = false;
- return( p );
- });
- });
- return( tg );
- }
-
- list<string> get_disk_try_list( map<string,map> tg, boolean soft )
- {
- list<string> ret = [];
- ret = maplist( string k, map e,
- filter( string l, map f, tg,
- ``(!ignore_disk(l,f,soft))), ``(k));
- ret = sort( ret );
- if( size(ret)>4 )
- {
- ret = restrict_disk_names( ret );
- }
- y2milestone( "get_disk_try_list soft:%1 ret:%2", soft, ret );
- return( ret );
- }
-
- boolean usable_for_win_resize( map p, boolean assert_cons_fs )
- {
- boolean ret = Partitions::IsDosWinNtPartition( p["fsid"]:0 ) &&
- p["size_k"]:0 > 1024*1024 &&
- !p["resize"]:false && !p["delete"]:false;
- if( ret )
- {
- if( assert_cons_fs )
- ret = p["winfo","ok"]:false;
- else
- ret = size(p["winfo"]:$[])>0;
- }
- return( ret );
- }
-
- list<map> remove_p_settings( list<map> parts, list<string> mp )
- {
- list<string> rems = [ "resize", "used_fs", "win_max_length", "mount",
- "format", "ignore_fs", "vg" ];
- parts =
- maplist( map p, parts,
- ``{
- if( size(mp)==0 || contains( mp, p["mount"]:"") )
- {
- foreach( string s, rems,
- ``{
- if( haskey( p, s ))
- p = remove( p, s );
- });
- }
- return( p );
- });
- return( parts );
- }
-
- list<map> remove_one_partition( list<map> partitions )
- {
- list<map> pl = filter( map p, partitions,
- ``( p["linux"]:false && size(p["mount"]:"")==0 &&
- !p["delete"]:false ));
- if( size(pl)>0 )
- {
- pl = sort( map a, map b, pl,
- ``(a["size_k"]:0>b["size_k"]:0));
- pl = (list<map>) union(
- filter( map p, pl, ``(p["used_by_type"]:`UB_NONE==`UB_NONE) ),
- filter( map p, pl, ``(p["used_by_type"]:`UB_NONE!=`UB_NONE) ));
-
- partitions =
- maplist( map p, partitions,
- ``{
- if( p["linux"]:false && !p["delete"]:false &&
- size(p["mount"]:"")==0 &&
- p["device"]:""==pl[0,"device"]:"" )
- {
- p["delete"] = true;
- y2milestone( "remove_one_partition p %1", p );
- }
- return( p );
- });
- partitions = try_remove_sole_extended( partitions );
- }
- return( partitions );
- }
-
- list<map> remove_one_partition_vm( map disk )
- {
- list<map> partitions = disk["partitions"]:[];
- list<map> pl = filter( map p, partitions,
- ``( p["linux"]:false && size(p["mount"]:"")==0 &&
- !p["delete"]:false ));
- if( size(pl)>0 )
- {
- pl = sort( map a, map b, pl,
- ``(a["size_k"]:0<b["size_k"]:0));
- pl = (list<map>) union(
- filter( map p, pl, ``(p["type"]:`primary==`logical) ),
- filter( map p, pl, ``(p["type"]:`primary!=`logical) ));
- pl = (list<map>) union(
- filter( map p, pl, ``(p["used_by_type"]:`UB_NONE==`UB_NONE) ),
- filter( map p, pl, ``(p["used_by_type"]:`UB_NONE!=`UB_NONE) ));
- y2milestone( "remove_one_partition_vm pl %1", pl );
-
- integer nr = 0;
-
- partitions =
- maplist( map p, partitions,
- ``{
- if( p["linux"]:false && !p["delete"]:false &&
- size(p["mount"]:"")==0 &&
- p["device"]:""==pl[0,"device"]:"" )
- {
- p["delete"] = true;
- nr = p["nr"]:0;
- y2milestone( "remove_one_partition_vm p %1", p );
- }
- return( p );
- });
- if( nr>disk["max_primary"]:4 )
- {
- partitions =
- maplist( map p, partitions,
- ``{
- if( !p["delete"]:false && p["nr"]:0>nr )
- {
- p["nr"] = p["nr"]:0-1;
- p["device"] = Storage::GetDeviceName( disk["device"]:"",
- p["nr"]:0 );
- y2milestone( "remove_one_partition_vm ren %1", p );
- }
- return( p );
- });
- }
- partitions = try_remove_sole_extended( partitions );
- }
- return( partitions );
- }
-
- map remove_used_by( map tg, string disk )
- {
- string uby = tg[disk,"used_by"]:"";
- y2milestone( "remove_used_by disk %1 uby %2", disk, uby );
- if( size(uby)>0 )
- {
- string k = "/dev/"+uby;
- if( haskey( tg, k ))
- {
- tg[k,"delete"] = true;
- y2milestone( "remove_used_by uby %1", tg[k]:$[] );
- }
- }
- return( tg );
- }
-
- map get_inst_proposal( map<string,map> target )
- {
- y2milestone( "get_inst_proposal start" );
- map ret = $[];
- target = Storage::AddWinInfo(target);
- ret["target"] = target;
- map root = $[ "mount" : "/", "increasable" : true,
- "fsys" : Partitions::DefaultFs(), "size" : 0 ];
- map opts = Storage::GetControlCfg();
- list<string> ddev = get_disk_try_list( target, true );
- string sol_disk = "";
- list modes = [ `free, `reuse, `remove, `resize, `desparate ];
- map<string,boolean> valid = $[];
- map<string,list> size_mb = listmap( string s, ddev, ``($[s:[]]));
- map solution = listmap( string s, ddev, ``($[s:[]]));
- target = prepare_part_lists( ddev, target );
- symbol mode = `free;
- while( mode != `end && size(sol_disk)==0 )
- {
- if( mode == `free || mode == `desparate )
- {
- valid = listmap( string s, ddev, ``($[s:true]));
- if( mode == `desparate )
- {
- ddev = get_disk_try_list( target, false );
- valid = listmap( string s, ddev, ``($[s:true]));
- target = prepare_part_lists( ddev, target );
- foreach( string s, ddev,
- ``{
- target[s,"partitions"] =
- remove_p_settings( target[s,"partitions"]:[], [] );
- target[s,"partitions"] =
- maplist( map p, target[s,"partitions"]:[],
- ``{
- if( !contains( Partitions::do_not_delete,
- p["fsid"]:0 ))
- {
- if( usable_for_win_resize(p,false) )
- p["dtxt"] = _("Resize impossible due to inconsistent fs. Try checking fs under Windows.");
- p["delete"] = true;
- }
- return( p );
- });
- });
- }
- }
- else if( mode == `reuse || mode == `remove )
- {
- valid = listmap( string s, ddev,
- ``{
- if( find( map p, target[s,"partitions"]:[],
- ``(p["linux"]:false && size(p["mount"]:"")==0 &&
- !p["delete"]:false)) != nil )
- return( $[s:true] );
- else
- return( $[s:false] );
- });
- if( mode == `remove )
- {
- foreach( string s, ddev,
- ``{
- target[s,"partitions"] =
- remove_p_settings( target[s,"partitions"]:[],
- ["/", "/home"] );
- });
- foreach( string s, filter( string d, ddev, ``(valid[d]:false)),
- ``{
- target[s,"partitions"] =
- remove_one_partition( target[s,"partitions"]:[] );
- });
- }
- }
- else if( mode == `resize )
- {
- valid = listmap( string s, ddev,
- ``{
- if( find( map p, target[s,"partitions"]:[],
- ``(usable_for_win_resize(p,true))) != nil )
- return( $[s:true] );
- else
- return( $[s:false] );
- });
- foreach( string s, filter( string d, ddev, ``(valid[d]:false)),
- ``{
- list<map> pl = filter( map p, target[s,"partitions"]:[],
- ``(usable_for_win_resize(p,true)));
- if( size(pl)>0 )
- {
- pl = sort( map a, map b, pl,
- ``(a["size_k"]:0>b["size_k"]:0));
- target[s,"partitions"] =
- maplist( map p, target[s,"partitions"]:[],
- ``{
- if( usable_for_win_resize(p,true) &&
- p["device"]:""==pl[0,"device"]:"" )
- {
- integer cs = target[s,"cyl_size"]:1;
- p["resize"] = true;
- p["region",1] =
- (p["winfo","new_size"]:0+cs-1) / cs;
- p["win_max_length"] =
- (p["winfo","max_win_size"]:0+cs-1) / cs;
- }
- return( p );
- });
- y2milestone( "get_inst_proposal res parts %1",
- target[s,"partitions"]:[] );
- }
- });
- }
- y2milestone( "get_inst_proposal mode %1 valid %2", mode, valid );
- foreach( string s, filter( string d, ddev, ``(valid[d]:false)),
- ``{
- map conf = $[ "partitions" : [] ];
- map disk = target[s]:$[];
- list<map> p = can_boot_reuse( s, disk["label"]:"msdos",
- need_boot(disk),
- disk["max_primary"]:4,
- disk["partitions"]:[] );
- disk["partitions"] =
- special_boot_proposal_prepare( disk["partitions"]:[] );
- boolean have_home = false;
- boolean have_root = false;
- boolean have_boot = (!Arch::ia64()||mode!=`free) && size(p)>0;
- if( have_boot )
- disk["partitions"] = p;
- map r = can_swap_reuse( s, disk["partitions"]:[], target );
- boolean have_swap = size(r)>0;
- if( haskey( r, "partitions" ))
- disk["partitions"] = r["partitions"]:[];
- else if( haskey( r, "targets" ))
- target = r["targets"]:$[];
- list swap_sizes = [];
- integer avail_size = get_usable_size_mb(disk,mode==`reuse);
- y2milestone( "get_inst_proposal disk %1 mode %2 avail %3",
- s, mode, avail_size );
- if( avail_size>0 )
- {
- if( mode == `reuse )
- {
- list<map> parts = disk["partitions"]:[];
- if( Storage::ProposalHome() )
- {
- if( avail_size > opts["home_limit"]:0 )
- parts = can_mp_reuse( "/home", 4*1024, 0, parts );
- else
- parts = can_mp_reuse( "/", opts["root_base"]:0, 0,
- parts );
- }
- if( size(parts)>0 && avail_size > opts["home_limit"]:0 )
- {
- integer mx = 0;
- if( Storage::ProposalHome() )
- mx = opts["root_max"]:0;
- parts = can_mp_reuse( "/", opts["root_base"]:0,
- mx, parts );
- }
- if( size(parts)>0 )
- {
- have_home = avail_size > opts["home_limit"]:0;
- have_root = true;
- disk["partitions"] = parts;
- }
- y2milestone( "get_inst_proposal reuse have_home %1 have_root %2",
- have_home, have_root );
- if( have_home && have_root )
- y2milestone( "get_inst_proposal reuse parts %1",
- disk["partitions"]:[] );
- }
- if( !have_swap )
- {
- swap_sizes = get_swap_sizes( avail_size );
- map swap = $[ "mount" : "swap", "increasable" : true,
- "fsys" : `swap, "maxsize" : 2*1024*1024*1024,
- "size" : swap_sizes[0]:256*1024*1024 ];
- conf["partitions"] = add( conf["partitions"]:[], swap );
- }
- if( !have_root )
- conf["partitions"] = add( conf["partitions"]:[], root );
- map old_root = $[];
- if( !have_home && Storage::ProposalHome() &&
- opts["home_limit"]:0 < avail_size )
- {
- map home = $[ "mount" : "/home", "increasable" : true,
- "fsys" : Partitions::DefaultFs(),
- "size" : 512*1024*1024,
- "pct" : 100-opts["root_percent"]:40 ];
- conf["partitions"] =
- maplist( map p, conf["partitions"]:[],
- ``{
- if( p["mount"]:""=="/" )
- {
- old_root = p;
- p["pct"] = opts["root_percent"]:40;
- p["maxsize"] = opts["root_max"]:0*1024*1024;
- p["size"] = opts["root_base"]:0*1024*1024;
- }
- return( p );
- });
- conf["partitions"] = add( conf["partitions"]:[], home );
- }
- map ps1 = do_flexible_disk_conf( disk, conf, have_boot,
- mode==`reuse );
- if( size(old_root)>0 && !ps1["ok"]:false )
- {
- conf["partitions"] =
- filter( map p, conf["partitions"]:[],
- ``(p["mount"]:""!="/home" &&
- p["mount"]:""!="/"));
- conf["partitions"] = add( conf["partitions"]:[], old_root );
- ps1 = do_flexible_disk_conf( disk, conf, have_boot,
- mode==`reuse );
- }
- if( !have_swap )
- {
- integer diff = swap_sizes[0]:256 - swap_sizes[1]:256;
- if( diff<0 )
- diff = -diff;
- y2milestone( "get_inst_proposal diff:%1 ps1 ok:%2",
- diff, ps1["ok"]:false );
- if( (!ps1["ok"]:false && diff>0) || diff>100 )
- {
- conf["partitions",0,"size"] =
- swap_sizes[1]:256*1024*1024;
- map ps2 = do_flexible_disk_conf( disk, conf, have_boot,
- mode==`reuse );
- y2milestone( "get_inst_proposal ps2 ok:%1",
- ps2["ok"]:false );
- if( ps2["ok"]:false )
- {
- map rp1 = find( map p, ps1["disk","partitions"]:[],
- ``(!p["delete"]:false &&
- p["mount"]:""=="/"));
- map rp2 = find( map p, ps2["disk","partitions"]:[],
- ``(!p["delete"]:false &&
- p["mount"]:""=="/"));
- y2milestone( "get_inst_proposal rp1:%1", rp1 );
- y2milestone( "get_inst_proposal rp2:%1", rp2 );
- if( rp1==nil ||
- (rp2!=nil && rp2["size_k"]:0>rp1["size_k"]:0 ))
- ps1 = ps2;
- }
- }
- }
- if( ps1["ok"]:false )
- {
- list mb = [ get_mb_sol( ps1, "/" )];
- if( Storage::ProposalHome() )
- mb = add( mb, get_mb_sol( ps1, "/home" ));
- if( mb[0]:0+mb[1]:0 > size_mb[s,0]:0 + size_mb[s,1]:0 )
- {
- solution[s] = ps1["disk"]:$[];
- size_mb[s] = mb;
- y2milestone( "get_inst_proposal sol %1 mb %2",
- s, size_mb[s]:[] );
- }
- }
- }
- });
- integer max_mb = 0;
- string max_disk = "";
- foreach( string s, list mb, size_mb,
- ``{
- if( (!Storage::ProposalHome() || mb[1]:0>0 || mode==`resize ) &&
- mb[1]:0+mb[0]:0 > max_mb )
- {
- max_mb = mb[1]:0+mb[0]:0;
- max_disk = s;
- }
- });
- y2milestone( "max_mb %1 size_mb %2", max_mb, size_mb );
- if( max_mb>0 && size_mb[max_disk,0]:0 > 2*1024 &&
- ( !Storage::ProposalHome() || size_mb[max_disk,1]:0 > 1*1024 ))
- {
- sol_disk = max_disk;
- }
- y2milestone( "get_inst_proposal mode %1 size_mb %2", mode, size_mb );
- if( size(sol_disk)==0 )
- {
- list<boolean> lb = maplist(string s, boolean e, valid, ``(e));
- if( mode == `free )
- mode = `reuse;
- else if( mode == `reuse )
- mode = `remove;
- else if( mode == `remove && find( boolean v, lb, ``(v)) == nil )
- mode = `resize;
- else if( mode == `resize && find( boolean v, lb, ``(v)) == nil )
- mode = `desparate;
- else if( mode == `desparate )
- mode = `end;
- if( mode == `desparate && size(sol_disk)==0 )
- {
- max_mb = 0;
- foreach( string s, list mb, size_mb,
- ``{
- if( mb[1]:0+mb[0]:0 > max_mb &&
- size_mb[max_disk,0]:0 > 2*1024 )
- {
- max_mb = mb[1]:0+mb[0]:0;
- sol_disk = s;
- }
- });
- y2milestone( "get_inst_proposal mode %1 sol_disk %2",
- mode, sol_disk );
- }
- }
- }
- y2milestone( "get_inst_proposal sol_disk %1", sol_disk );
- if( size(sol_disk)==0 )
- {
- integer max_mb = 0;
- foreach( string s, list mb, size_mb,
- ``{
- if( mb[1]:0+mb[0]:0>max_mb )
- {
- max_mb = mb[1]:0+mb[0]:0;
- sol_disk = s;
- }
- });
- y2milestone( "get_inst_proposal sol_disk %1", sol_disk );
- }
- ret["ok"] = size(sol_disk)>0;
- if( ret["ok"]:false )
- {
- ret["target"] = remove_used_by( ret["target"]:$[], sol_disk );
- ret["target",sol_disk] = solution[sol_disk]:$[];
- ret["target"] = Storage::SpecialBootHandling( ret["target"]:$[] );
- y2milestone( "get_inst_proposal sol:%1", ret["target",sol_disk]:$[] );
- }
- y2milestone( "get_inst_proposal ret[ok]:%1", ret["ok"]:false );
- return( ret );
- }
-
- list<map> remove_keys( list<map> pl, list<string> keys )
- {
- pl = maplist( map p, pl,
- ``{
- foreach( string k, keys,
- ``{
- if( haskey(p,k) )
- p = remove( p, k );
- });
- return( p );
- });
- return( pl );
- }
-
- map<string,map> remove_mount_points( map<string,map> target )
- {
- foreach( string s, map disk, target,
- ``{
- target[s,"partitions"] = remove_keys( target[s,"partitions"]:[],
- [ "mount" ] );
- });
- return( target );
- }
-
- map<string,map> remove_vm( map<string,map> tg, string ky )
- {
- y2milestone( "remove_vm key:%1", ky );
- string key = "/dev/" + ky;
- if( haskey( tg, key ))
- {
- tg[key,"delete"] = true;
- tg[key,"partitions"] =
- maplist( map p, tg[key,"partitions"]:[],
- ``{
- p["delete"] = true;
- return(p);
- });
- y2milestone( "remove_vm removed:%1", tg[key]:$[] );
- list<string> dl = tg[key,"devices"]:[];
- foreach( string d, dl,
- ``{
- tg = Storage::DelPartitionData( tg, d, "used_by" );
- tg = Storage::DelPartitionData( tg, d, "used_by_type" );
- });
- }
- if( haskey( tg, "/dev/evms/lvm/"+ky ) || haskey( tg, "/dev/evms/lvm2/"+ky ))
- {
- if( haskey( tg, "/dev/evms/lvm/"+ky ) && tg[key,"lvm2"]:false )
- {
- key = "/dev/evms/lvm/"+ky;
- tg[key,"delete"] = true;
- tg[key,"partitions"] =
- maplist( map p, tg[key,"partitions"]:[],
- ``{
- p["delete"] = true;
- return(p);
- });
- y2milestone( "remove_vm removed:%1", tg[key]:$[] );
- list<string> dl = tg[key,"devices"]:[];
- foreach( string d, dl,
- ``{
- tg = Storage::DelPartitionData( tg, d, "used_by" );
- tg = Storage::DelPartitionData( tg, d, "used_by_type" );
- });
- }
- if( haskey( tg, "/dev/evms/lvm2/"+ky ) && !tg[key,"lvm2"]:false )
- {
- key = "/dev/evms/lvm2/"+ky;
- tg[key,"delete"] = true;
- tg[key,"partitions"] =
- maplist( map p, tg[key,"partitions"]:[],
- ``{
- p["delete"] = true;
- return(p);
- });
- y2milestone( "remove_vm removed:%1", tg[key]:$[] );
- list<string> dl = tg[key,"devices"]:[];
- foreach( string d, dl,
- ``{
- tg = Storage::DelPartitionData( tg, d, "used_by" );
- tg = Storage::DelPartitionData( tg, d, "used_by_type" );
- });
- }
- }
- return( tg );
- }
-
- string find_vm( map<string,map> target, string ky, integer min_size )
- {
- string ret = "";
- string key = "/dev/" + ky;
- string key2 = "/dev/evms/lvm2/" + ky;
- if( Storage::ProposalLvm() && target[key,"lvm2"]:false &&
- target[key,"size_k"]:0 >= min_size )
- ret = key;
- else if( Storage::ProposalEvms() && haskey( target, key2 ) &&
- target[key2,"size_k"]:0 >= min_size )
- ret = key2;
- y2milestone( "find_vm key:%1 min_size:%2 ret:%3", ky, min_size, ret );
- return( ret );
- }
-
- boolean did_remove_vg( list<map> partitions, string vg )
- {
- boolean ret=false;
- list<string> ele = [ vg, "lvm/"+vg, "lvm2/"+vg ];
- foreach( map p, partitions,
- ``{
- if( !ret && p["delete"]:false && contains( ele, p["used_by"]:"" ))
- ret = true;
- });
- y2milestone( "did_remove_vg vg:%1 ret:%2", vg, ret );
- return( ret );
- }
-
- integer sizek_to_pe( integer pek, integer pebyte, boolean pvcreate )
- {
- integer ret = (pek-(pvcreate?500:0)) / (pebyte/1024);
- y2milestone( "sizek_to_pe pek %1 pebyte %2 pvcreate %3 ret %4",
- pek, pebyte, pvcreate, ret );
- return( ret );
- }
-
- integer pe_to_sizek( integer pe, integer pebyte )
- {
- integer ret = pe * (pebyte/1024);
- y2milestone( "pe_to_sizek pe %1 pebyte %2 ret %3", pe, pebyte, ret );
- return( ret );
- }
-
- map extend_vm( map vg, string key, map disk )
- {
- y2milestone( "extend_vm key %1 vg %2", key, vg );
- y2milestone( "extend_vm disk %1", disk );
- list devs = [];
- integer num_pe = vg["pe_free"]:0;
- foreach( map p, disk["partitions"]:[],
- ``{
- if( p["vg"]:""==key )
- {
- devs = add( devs, p["device"]:"" );
- num_pe = num_pe +
- sizek_to_pe( p["size_k"]:0, vg["pesize"]:1024, true );
- };
- });
- y2milestone( "extend_vm num_pe %1 devs %2", num_pe, devs );
- vg["devices_add"] = devs;
- vg["pe_free"] = num_pe;
- vg["size_k"] = pe_to_sizek( num_pe, vg["pesize"]:0 );
- y2milestone( "extend_vm ret %1", vg );
- return( vg );
- }
-
- map create_vm( boolean evms, string key, map disk )
- {
- y2milestone( "create_vm evms %1 key %2 disk %3", evms, key, disk );
- map ret = $[ "type" : evms?`CT_EVMS:`CT_LVM,
- "name" : evms?"lvm2/"+key:key,
- "device" : "/dev/"+(evms?"evms/lvm2/":"")+key,
- "lvm2" : true,
- "create" : true,
- "partitions" : [],
- "pesize" : 4*1024*1024 ];
- list devs = [];
- integer num_pe = 0;
- foreach( map p, disk["partitions"]:[],
- ``{
- if( p["vg"]:""==key && !p["delete"]:false )
- {
- devs = add( devs, p["device"]:"" );
- num_pe = num_pe +
- sizek_to_pe( p["size_k"]:0, ret["pesize"]:1024, true );
- };
- });
- y2milestone( "create_vm num_pe %1 devs %2", num_pe, devs );
- ret["devices_add"] = devs;
- ret["pe_free"] = num_pe;
- ret["size_k"] = pe_to_sizek( num_pe, ret["pesize"]:0 );
- y2milestone( "create_vm ret %1", ret );
- return( ret );
- }
-
- integer round_mb_pe( integer mb, integer pebyte )
- {
- integer pek = pebyte/1024;
- if( pek<1 )
- pek = 1;
- integer ret = (mb*1024 + pek-1) / pek * pek;
- if( ret==0 )
- ret=1;
- y2milestone( "round_mb_pe mb %1 pebyte %2 ret %3", mb, pebyte, ret );
- return( ret );
- }
-
- map modify_vm( map vm, map opts, boolean need_swap )
- {
- y2milestone( "modify_vm swap %1 start %2", need_swap, vm );
- y2milestone( "modify_vm opts %1", opts );
- map ret = vm;
- integer free = ret["pe_free"]:0;
- integer pe = ret["pesize"]:1024;
- integer swsize = 0;
- list swlist = [];
- if( need_swap )
- {
- swlist = get_swap_sizes( free );
- swsize = (swlist[1]:0>swlist[0]:0) ? swlist[1]:0 : swlist[0]:0;
- }
- y2milestone( "modify_vm swsize %1", swsize );
- map swap = find( map p, ret["partitions"]:[], ``(p["name"]:""=="swap"));
- map root = find( map p, ret["partitions"]:[], ``(p["name"]:""=="root"));
- map home = find( map p, ret["partitions"]:[], ``(p["name"]:""=="home"));
- y2milestone( "modify_vm swap %1 root %2 home %3", swap, root, home );
- if( root!=nil && root["size_k"]:0<1024*1024 )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == "root" )
- {
- p["delete"] = true;
- free = free + sizek_to_pe( p["size_k"]:0, pe, false );
- y2milestone( "modify_vm remove root %1", p );
- }
- return(p);
- });
- y2milestone( "modify_vm pe free %1", free );
- root = nil;
- }
- ret["partitions"] = sort( map a, map b, ret["partitions"]:[],
- ``(a["size_k"]:0>b["size_k"]:0));
- list keep = [ "root", "home", "swap" ];
- integer root_pe = sizek_to_pe( opts["root_base"]:0*1024, pe, false );
- y2milestone( "modify_vm pe free %1 root %2", free, root_pe );
- map m = find( map p, ret["partitions"]:[],
- ``(!p["delete"]:false && !contains(keep,p["name"]:"")));
- while( root==nil && free<root_pe && m!=nil )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == m["name"]:"" )
- {
- p["delete"] = true;
- free = free + sizek_to_pe( p["size_k"]:0, pe, false );
- }
- return(p);
- });
- y2milestone( "modify_vm pe free %1 root %2 del %3", free, root_pe, m );
- m = find( map p, ret["partitions"]:[],
- ``(!p["delete"]:false && !contains(keep,p["name"]:"")));
- }
- if( root==nil && free<root_pe && swap!=nil && swsize==0 )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == "swap" )
- {
- p["delete"] = true;
- free = free + sizek_to_pe( p["size_k"]:0, pe, false );
- }
- return(p);
- });
- swap = nil;
- y2milestone( "modify_vm pe free %1 root %2", free, root_pe );
- }
- if( root==nil && free<root_pe && swsize>0 )
- {
- swsize = (swlist[1]:0<swlist[0]:0) ? swlist[1]:0 : swlist[0]:0;
- y2milestone( "modify_vm new swsize %1", swsize );
- }
- if( root==nil && free<root_pe && swap!=nil && swsize<swap["size_k"]:0/1024 )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == "swap" )
- {
- p["delete"] = true;
- free = free + sizek_to_pe( p["size_k"]:0, pe, false );
- }
- return(p);
- });
- swap = nil;
- y2milestone( "modify_vm pe free %1 root %2", free, root_pe );
- }
- integer swap_pe = 0;
- integer home_pe = 0;
- if( swap==nil && swsize>0 )
- swap_pe = sizek_to_pe( swsize*1024, pe, false );
- if( free<root_pe+swap_pe )
- {
- y2milestone( "modify_vm pe free %1 root %2 swap %3",
- free, root_pe, swap_pe );
- if( root==nil && swap_pe>free )
- {
- swap_pe = free;
- free = 0;
- }
- else if( swap_pe==0 )
- {
- root_pe = free;
- free = 0;
- }
- else
- {
- swap_pe = swap_pe*free/(root_pe+swap_pe);
- root_pe = free-swap_pe;
- free = 0;
- }
- y2milestone( "modify_vm pe free %1 root %2 swap %3",
- free, root_pe, swap_pe );
- }
- else
- {
- free = free-swap_pe;
- y2milestone( "modify_vm pe free %1 root %2 swap %3",
- free, root_pe, swap_pe );
- if( home==nil && Storage::ProposalHome() &&
- free>sizek_to_pe( opts["home_limit"]:0*1024, pe, false ) )
- {
- integer tmp = free * opts["root_percent"]:40 / 100;
- if( tmp>root_pe )
- root_pe=tmp;
- tmp = sizek_to_pe( opts["root_max"]:0*1024, pe, false );
- if( root_pe>tmp )
- root_pe=tmp;
- free = free-root_pe;
- home_pe = free;
- tmp = sizek_to_pe( opts["home_max"]:0*1024, pe, false );
- if( home_pe>tmp )
- home_pe = tmp;
- free = free-home_pe;
- y2milestone( "modify_vm pe free %1 root %2 home %3",
- free, root_pe, home_pe );
- }
- else
- {
- integer tmp = sizek_to_pe( opts["root_max"]:0*1024, pe, false );
- root_pe = free;
- if( root_pe>tmp )
- root_pe=tmp;
- free = free-root_pe;
- }
- }
- y2milestone( "modify_vm pe free %1 root %2 swap %3 home %4",
- free, root_pe, swap_pe, home_pe );
- if( root==nil && root_pe>0 )
- {
- map p = $[ "create":true, "name" : "root",
- "format":true, "used_fs" : Partitions::DefaultFs(),
- "device" : ret["device"]:"" + "/root",
- "mount" : "/",
- "size_k" : pe_to_sizek(root_pe,pe) ];
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- y2milestone( "modify_vm created %1", p );
- ret["partitions"] = add( ret["partitions"]:[], p );
- }
- else if( root!=nil )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == "root" )
- {
- p["mount"] = "/";
- p["format"] = true;
- if( p["detected_fs"]:`unknown==`unknown )
- {
- p["used_fs"] = Partitions::DefaultFs();
- }
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- y2milestone( "modify_vm reuse %1", p );
- }
- return(p);
- });
- }
- if( swap==nil && swap_pe>0 )
- {
- map p = $[ "create":true, "name" : "swap",
- "format":true, "used_fs" : `swap,
- "device" : ret["device"]:"" + "/swap",
- "mount" : "swap",
- "size_k" : pe_to_sizek(swap_pe,pe) ];
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- y2milestone( "modify_vm created %1", p );
- ret["partitions"] = add( ret["partitions"]:[], p );
- }
- else if( swap!=nil )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == "swap" )
- {
- p["mount"] = "swap";
- if( p["detected_fs"]:`unknown!=`swap )
- {
- p["format"] = true;
- p["used_fs"] = `swap;
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- }
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- y2milestone( "modify_vm reuse %1", p );
- }
- return(p);
- });
- }
- if( home==nil && home_pe>0 )
- {
- map p = $[ "create":true, "name" : "home",
- "format":true, "used_fs" : Partitions::DefaultFs(),
- "device" : ret["device"]:"" + "/home",
- "mount" : "/home",
- "size_k" : pe_to_sizek(home_pe,pe) ];
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- y2milestone( "modify_vm created %1", p );
- ret["partitions"] = add( ret["partitions"]:[], p );
- }
- else if( home!=nil )
- {
- ret["partitions"] = maplist( map p, ret["partitions"]:[],
- ``{
- if( p["name"]:"" == "home" )
- {
- p["mount"] = "/home";
- if( p["detected_fs"]:`unknown==`unknown )
- {
- p["format"] = true;
- p["used_fs"] = Partitions::DefaultFs();
- p["fs_options"] = FileSystems::DefaultFormatOptions( p );
- }
- p["fstopt"] = FileSystems::DefaultFstabOptions( p );
- y2milestone( "modify_vm reuse %1", p );
- }
- return(p);
- });
- }
- y2milestone( "modify_vm ret %1", ret );
- return( ret );
- }
-
- map get_inst_prop_vm( map<string,map> target, string key )
- {
- y2milestone( "get_inst_prop_vm start key %1", key );
- map ret = $[];
- map opts = Storage::GetControlCfg();
- string vg_key = find_vm( target, key, opts["root_base"]:0*1024 );
- target = remove_mount_points(target);
- if( size(vg_key)==0 )
- target = remove_vm(target,key);
- target = Storage::AddWinInfo(target);
- ret["target"] = target;
- map boot = $[ "mount" : Partitions::BootMount(),
- "size" : Partitions::MinimalNeededBootsize(),
- "fsys" : Partitions::DefaultBootFs(),
- "id" : Partitions::FsidBoot(),
- "max_cyl" : Partitions::BootCyl() ];
- if( Partitions::BootPrimary() )
- {
- boot["primary"] = true;
- }
- list<string> ddev = get_disk_try_list( target, true );
- string sol_disk = "";
- list modes = [ `free, `remove, `resize, `desparate ];
- map<string,boolean> valid = $[];
- map<string,integer> size_mb = listmap( string s, ddev, ``($[s:0]));
- map<string,boolean> keep_vg = $[];
- map solution = listmap( string s, ddev, ``($[s:[]]));
- target = prepare_part_lists( ddev, target );
- symbol mode = `free;
- while( mode != `end && size(sol_disk)==0 )
- {
- if( mode == `free || mode == `desparate )
- {
- valid = listmap( string s, ddev, ``($[s:true]));
- if( mode == `desparate )
- {
- ddev = get_disk_try_list( target, false );
- valid = listmap( string s, ddev, ``($[s:true]));
- target = prepare_part_lists( ddev, target );
- foreach( string s, ddev,
- ``{
- target[s,"partitions"] =
- remove_p_settings( target[s,"partitions"]:[], [] );
- target[s,"partitions"] =
- maplist( map p, target[s,"partitions"]:[],
- ``{
- if( !contains( Partitions::do_not_delete,
- p["fsid"]:0 ))
- {
- if( usable_for_win_resize(p,false) )
- p["dtxt"] = _("Resize impossible due to inconsistent fs. Try checking fs under Windows.");
- p["delete"] = true;
- }
- return( p );
- });
- });
- }
- }
- else if( mode == `remove )
- {
- valid = listmap( string s, ddev,
- ``{
- if( find( map p, target[s,"partitions"]:[],
- ``(p["linux"]:false && size(p["mount"]:"")==0 &&
- !p["delete"]:false)) != nil )
- return( $[s:true] );
- else
- return( $[s:false] );
- });
- foreach( string s, filter( string d, ddev, ``(valid[d]:false)),
- ``{
- target[s,"partitions"] =
- remove_one_partition_vm( target[s]:$[] );
- });
- }
- else if( mode == `resize )
- {
- valid = listmap( string s, ddev,
- ``{
- if( find( map p, target[s,"partitions"]:[],
- ``(usable_for_win_resize(p,true))) != nil )
- return( $[s:true] );
- else
- return( $[s:false] );
- });
- foreach( string s, filter( string d, ddev, ``(valid[d]:false)),
- ``{
- list<map> pl = filter( map p, target[s,"partitions"]:[],
- ``(usable_for_win_resize(p,true)));
- if( size(pl)>0 )
- {
- pl = sort( map a, map b, pl,
- ``(a["size_k"]:0>b["size_k"]:0));
- target[s,"partitions"] =
- maplist( map p, target[s,"partitions"]:[],
- ``{
- if( usable_for_win_resize(p,true) &&
- p["device"]:""==pl[0,"device"]:"" )
- {
- integer cs = target[s,"cyl_size"]:1;
- p["resize"] = true;
- p["region",1] =
- (p["winfo","new_size"]:0+cs-1) / cs;
- p["win_max_length"] =
- (p["winfo","max_win_size"]:0+cs-1) / cs;
- }
- return( p );
- });
- y2milestone( "get_inst_prop_vm res parts %1",
- target[s,"partitions"]:[] );
- }
- });
- }
- y2milestone( "get_inst_prop_vm mode %1 valid %2", mode, valid );
- foreach( string s, filter( string d, ddev, ``(valid[d]:false)),
- ``{
- map disk = target[s]:$[];
- map conf = $[ "partitions" : [] ];
- list<map> p = can_boot_reuse( s, disk["label"]:"msdos", true,
- disk["max_primary"]:4,
- disk["partitions"]:[] );
- disk["partitions"] =
- special_boot_proposal_prepare( disk["partitions"]:[] );
- boolean have_boot = size(p)>0;
- if( have_boot )
- disk["partitions"] = p;
- string vg = vg_key;
- if( size(vg)>0 && did_remove_vg( disk["partitions"]:[], key ))
- vg = "";
- map ps = do_vm_disk_conf( disk, have_boot?($[]):boot, vg, key );
- if( ps["ok"]:false )
- {
- integer mb = get_vm_sol( ps );
- if( mb-size_mb[s]:0>size_mb[s]:0/40 )
- {
- y2milestone( "get_inst_prop_vm new sol %1 old %2 new %3",
- s, size_mb[s]:0, mb );
- solution[s] = ps["disk"]:$[];
- size_mb[s] = mb;
- }
- if( size(vg)>0 && !keep_vg[s]:false )
- keep_vg[s] = true;
- }
- });
- y2milestone( "get_inst_prop_vm size_mb %1 keep_vg %2",
- size_mb, keep_vg );
- integer max_mb = 0;
- string max_disk = "";
- string keep_disk = "";
- foreach( string s, integer mb, size_mb,
- ``{
- if( mb > max_mb )
- {
- max_mb = mb;
- max_disk = s;
- }
- });
- foreach( string s, boolean keep, keep_vg,
- ``{
- if( size(keep_disk)==0 && keep )
- {
- keep_disk = s;
- }
- });
- if( size(keep_disk)>0 )
- {
- sol_disk = keep_disk;
- }
- else if( max_mb>0 && size_mb[max_disk]:0 > opts["vm_want"]:(20*1024) )
- {
- sol_disk = max_disk;
- vg_key = "";
- }
- y2milestone( "get_inst_prop_vm mode %1 sol_disk %2", mode, sol_disk );
- if( size(sol_disk)==0 )
- {
- list<boolean> lb = maplist(string s, boolean e, valid, ``(e));
- if( mode == `free )
- mode = `remove;
- else if( mode == `remove && find( boolean v, lb, ``(v)) == nil )
- mode = `resize;
- else if( mode == `resize && find( boolean v, lb, ``(v)) == nil )
- mode = `desparate;
- else if( mode == `desparate )
- mode = `end;
- }
- }
- y2milestone( "get_inst_prop_vm sol_disk %1", sol_disk );
- if( size(sol_disk)==0 )
- {
- integer max_mb = 0;
- foreach( string s, integer mb, size_mb,
- ``{
- if( mb>max_mb )
- {
- max_mb = mb;
- sol_disk = s;
- }
- });
- y2milestone( "get_inst_prop_vm sol_disk %1", sol_disk );
- }
- ret["ok"] = size(sol_disk)>0;
- if( ret["ok"]:false )
- {
- map r = can_swap_reuse( sol_disk, solution[sol_disk,"partitions"]:[],
- ret["target"]:$[] );
- if( haskey( r, "partitions" ))
- solution[sol_disk,"partitions"] = r["partitions"]:[];
- else if( haskey( r, "targets" ))
- ret["target"] = r["targets"]:$[];
- ret["target"] = remove_used_by( ret["target"]:$[], sol_disk );
- if( size(vg_key)==0 )
- {
- vg_key = (Storage::ProposalEvms()?"/dev/evms/lvm2/":"/dev/")+key;
- map vg = ret["target",vg_key]:$[];
- vg = union( vg, create_vm( Storage::ProposalEvms(), key,
- solution[sol_disk]:$[] ));
- if( size(vg["devices"]:[])>0 )
- {
- vg = remove( vg, "devices" );
- }
- y2milestone( "get_inst_prop_vm vkey %1", vg );
- ret["target",vg_key] = vg;
- }
- else
- {
- map vg = ret["target",vg_key]:$[];
- vg = extend_vm( vg, key, solution[sol_disk]:$[] );
- ret["target",vg_key] = vg;
- }
- ret["target",vg_key] = modify_vm( ret["target",vg_key]:$[], opts,
- size(r)==0 );
- ret["target",sol_disk] = solution[sol_disk]:$[];
- ret["target"] = Storage::SpecialBootHandling( ret["target"]:$[] );
- y2milestone( "get_inst_prop_vm sol:%1", ret["target",sol_disk]:$[] );
- }
- y2milestone( "get_inst_prop_vm ret[ok]:%1", ret["ok"]:false );
- return( ret );
- }
-
- map get_proposal_vm( map<string,map> target, string key, map disk )
- {
- string ddev = disk["device"]:"";
- y2milestone( "get_proposal_vm ddev:%1 vg:%2 evms:%3 lvm:%4 home:%5", ddev,
- key, Storage::ProposalEvms(), Storage::ProposalLvm(),
- Storage::ProposalHome() );
- map ret = $[];
- map opts = Storage::GetControlCfg();
- target = remove_mount_points(target);
- target = remove_vm(target,key);
- ret["target"] = target;
- map boot = $[ "mount" : Partitions::BootMount(),
- "size" : Partitions::MinimalNeededBootsize(),
- "fsys" : Partitions::DefaultBootFs(),
- "id" : Partitions::FsidBoot(),
- "max_cyl" : Partitions::BootCyl() ];
- if( Partitions::BootPrimary() )
- {
- boot["primary"] = true;
- }
- map conf = $[ "partitions" : [] ];
- list<map> p = can_boot_reuse( ddev, disk["label"]:"msdos", true,
- disk["max_primary"]:4,
- disk["partitions"]:[] );
- disk["partitions"] = special_boot_proposal_prepare( disk["partitions"]:[] );
- boolean have_boot = size(p)>0;
- if( have_boot )
- disk["partitions"] = p;
- map ps = do_vm_disk_conf( disk, have_boot?($[]):boot, "", key );
- ret["ok"] = ps["ok"]:false;
- if( ret["ok"]:false )
- {
- disk = ps["disk"]:$[];
- map r = can_swap_reuse( ddev, disk["partitions"]:[],
- ret["target"]:$[] );
- if( haskey( r, "partitions" ))
- disk["partitions"] = r["partitions"]:[];
- else if( haskey( r, "targets" ))
- ret["target"] = r["targets"]:$[];
- ret["target"] = remove_used_by( ret["target"]:$[], ddev );
- string vg_key = (Storage::ProposalEvms()?"/dev/evms/lvm2/":"/dev/")+key;
- map vg = ret["target",vg_key]:$[];
- vg = union( vg, create_vm( Storage::ProposalEvms(), key, disk ));
- if( size(vg["devices"]:[])>0 )
- {
- vg = remove( vg, "devices" );
- }
- y2milestone( "get_proposal_vm vkey %1", vg );
- ret["target",vg_key] = modify_vm( vg, opts, size(r)==0 );
- ret["target",ddev] = disk;
- ret["target"] = Storage::SpecialBootHandling( ret["target"]:$[] );
- y2milestone( "get_proposal_vm sol:%1", disk );
- }
- y2milestone( "get_proposal_vm ret[ok]:%1", ret["ok"]:false );
- return( ret );
- }
-
- map get_inst_prop( map<string,map> target )
- {
- map ret = $[];
- string vg = Storage::ProposalVM();
- y2milestone( "get_inst_prop vg:%1 evms:%2 lvm:%3 home:%4", vg,
- Storage::ProposalEvms(), Storage::ProposalLvm(),
- Storage::ProposalHome() );
- if( size(vg)==0 )
- ret = get_inst_proposal( target );
- else
- {
- if( Storage::ProposalEvms() &&
- size(target["/dev/evms","partitions"]:[])==0 )
- {
- Storage::ActivateEvms();
- target = Storage::GetTargetMap();
- }
- ret = get_inst_prop_vm( target, vg );
- }
- return( ret );
- }
-
- }
-
-