home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
include
/
partitioning
/
evms_lib.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
36KB
|
1,322 lines
/**
* File:
* evms_lib.ycp
*
* Module:
* utility functions for evms config
*
* Summary:
*
* Authors:
* Thomas Fehr <fehr@suse.de>
*
*
* $Id: evms_lib.ycp 33366 2006-10-12 14:55:19Z fehr $
*
*/
{
textdomain "storage";
import "FileSystems";
import "Storage";
import "Mode";
include "partitioning/partition_defines.ycp";
//////////////////////////////////////////////////////////////////////
// helptext for evms main dialog
//////////////////////////////////////////////////////////////////////
define string getEvmsHelptext()
``{
string help_text = "";
// helptext EVMS partitioning.
help_text = _("<p>The upper part of this dialog contains the container-related functionality. Here, create, edit, and modify EVMS containers. </p>");
// helptext EVMS partitioning.
help_text = help_text + _("<p>
The lower part with the list contains all available EVMS devices.
If at least one EVMS container is available, you can create new
devices that use the available space of the current container.</p>
");
return( help_text );
};
//////////////////////////////////////////////////////////////////////
// evms_pesize_check
// in: <number>[kKmM][bB]
//
// return 0 if input is invalid
//
// pesize is valid 8K to 512M in power of 2
// 8 is 8k
// 16K == 16k == 16KB == 16kb
define integer evms_pesize_check( string input, string type )
``{
integer num = kmgt_str_to_byte( input );
if( findfirstnotof( input, "0123456789 " ) == nil )
num = num*1024;
integer ret = num;
if( ret % 1024 != 0 )
ret = 0;
else
{
while( num>1 && ret>0 )
{
if( num%2 != 0 )
ret = 0;
else
num = num/2;
}
}
y2milestone( "evms_pesize_check ret %1", ret );
if( ret < 8*1024 || ret > 512*1024*1024*1024 )
{
ret = 0;
}
y2milestone( "evms_pesize_check ret %1", ret );
if( ret==0 )
{
// error popup text
Popup::Error(_("The data entered is invalid.
Insert a physical extent size from
8KB to 512GB in powers of 2, for example, 4M or 512K.
"));
}
return( ret );
};
//////////////////////////////////////////////////////////////////////
// checks if name is a valid container name
define boolean evms_check_name( string name )
``{
if ( size( name ) == 0 ) return( false );
return( ( findfirstof( name, " ;/`'┬┤!,\"%#" ) == nil ) );
}
define string evms_dev_disk( string dev )
{
return( Storage::EvmsDevDisk( dev ));
}
define list<map> filter_deleted_parts( map<string,map> tg, list<map> plist )
``{
list<map> ret = [];
foreach( map p, plist,
``{
if( search( p["device"]:"", "/dev/evms/" )==0 )
{
map disk =
Storage::GetDiskPartition( evms_dev_disk( p["device"]:"" ));
if( size(filter( map pa, tg[disk["disk"]:"","partitions"]:[],
``(sformat("%1",pa["nr"]:(any)"")==
sformat("%1",disk["nr"]:(any)0) &&
pa["delete"]:false)))==0)
{
ret = add( ret, p );
}
}
else
{
ret = add( ret, p );
}
});
if( size(plist)!=size(ret) )
{
y2milestone( "filter_deleted_parts plist %1", plist );
y2milestone( "filter_deleted_parts ret %1", ret );
}
return( ret );
}
define list<map> filter_mounted_evms_part( map<string,map> tg, list<map> pa )
{
list<map> ret = filter( map p, pa,
``{
boolean ok = p["evms_native"]:false;
if( !ok )
{
string dev = evms_dev_disk( p["device"]:"" );
map part = Storage::GetPartition( tg, dev );
ok = size(part["mount"]:"")==0;
}
return( ok );
});
return( ret );
}
define list<map> filter_used_disk_evms_part( map<string,map> tg, list<map> pa, string name )
{
boolean ok = false;
list<map> ret = filter( map p, pa,
``{
string dev = evms_dev_disk( p["device"]:"" );
ok = tg[dev,"used_by_type"]:`UB_NONE == `UB_NONE ||
(tg[dev,"used_by_type"]:`UB_NONE == `UB_EVMS &&
tg[dev,"used_by"]:"" == name);
return( ok );
});
return( ret );
}
define list<map> get_pvlist( map<string,map> tg, string name )
``{
list<map> pv = [];
y2milestone( "get_pvlist name %1", name );
foreach( string k, map e, tg,
``{
if( e["type"]:`CT_UNKNOWN==`CT_EVMS )
{
if( !e["is_container"]:false )
{
list<map> tmp = filter( map p, e["partitions"]:[],
``(p["used_by_type"]:`UB_NONE==`UB_NONE ||
(p["used_by_type"]:`UB_NONE==`UB_EVMS &&
p["used_by"]:""==name)));
tmp = filter( map p, tmp, ``(size(p["mount"]:"")==0));
tmp = filter_mounted_evms_part( tg, tmp );
tmp = filter_used_disk_evms_part( tg, tmp, name );
y2milestone( "key %1 tmp %2", k, tmp );
pv = (list<map>)merge( pv, tmp );
}
}
else
{
y2milestone( "get_pvlist key %1 disk %2", k, e );
list<map> tmp = filter( map p, e["partitions"]:[],
``(size(name)>0 &&
p["used_by_type"]:`UB_NONE==`UB_EVMS &&
p["used_by"]:""==name ));
tmp = (list<map>)merge( tmp,
filter( map p, e["partitions"]:[],
``(p["type"]:`primary != `extended &&
size(p["mount"]:"")==0 &&
p["used_by_type"]:`UB_NONE==`UB_NONE)));
y2milestone( "get_pvlist tmp %1", tmp );
y2milestone( "key %1 tmp %2", k, tmp );
pv = (list<map>)merge( pv, tmp );
}
});
pv = maplist( map p, pv,
``{
string d = substring( p["device"]:"", 5 );
if( search( d, "evms/" )==0 )
{
d = substring( d, 5 );
}
p["device"] = d;
return( p );
});
pv = filter( map p, pv, ``(search(p["device"]:"","md/md")!=0));
pv = sort( map a, map b, pv, ``(a["device"]:""<b["device"]:""));
y2milestone( "pv %1", pv );
string pdev = "";
pv = filter( map p, pv,
``({
boolean r = false;
if( pdev!=p["device"]:"" )
{
pdev = p["device"]:"";
r = true;
}
return( r );
}));
y2milestone( "unique %1", pv );
return( pv );
}
define list<term> get_table_entries( list<map> pvlist, string name )
``{
y2milestone( "get_table_entries name %1", name );
integer count=-1;
list<term> ret = maplist( map p, pvlist,
``{
count = count+1;
return( `item( `id(count), p["device"]:"",
ByteToHumanStringWithZero(p["size_k"]:0*1024),
size(p["used_by"]:"")>0?" "+name:"" ));
});
y2milestone( "get_table_entries ret %1", ret );
return( ret );
}
define integer evms_usable_size( integer siz, integer pesize )
``{
integer r = siz - 128*1024;
r = (r/pesize)*pesize;
if( r < 0 ) r = 0;
return( r );
}
define integer get_container_size( map co, list pvlist )
``{
integer ret = co["size_k"]:0 * 1024;
y2milestone( "get_container_size ret %1", ret );
return( ret );
}
define void set_container_size( map co, integer new_size )
``{
string s = ByteToHumanStringWithZero( new_size );
UI::ChangeWidget( `id(`size), `Value, s );
UI::RecalcLayout();
}
define list get_index_list( list<string> l, list pvlist )
``{
list nl = [];
foreach( string e, l,
``{
integer i=0;
while( i<size(pvlist) && pvlist[i,"device"]:""!=e )
{
i = i+1;
}
if( i<size(pvlist) )
{
nl = add( nl, i );
}
});
y2milestone( "get_index_list l %1 ret %2", l, nl );
return( nl );
}
define void set_table_elements( list<term> entries, integer id )
``{
if( id < 0 )
{
id = (integer) UI::QueryWidget( `id(`pv_table), `CurrentItem );
}
UI::ChangeWidget( `id(`pv_table), `Items, entries );
UI::ChangeWidget( `id(`pv_table), `CurrentItem, id );
}
define map dlg_modify_container( map<string,map> tg, map<string,any> co,
boolean create )
``{
string old_name = co["name"]:"";
integer old_pesize = co["pesize"]:0;
// popup header
string head = _("Modify Existing EVMS Container");
if( co["create"]:false )
{
if( create )
{
// popup header
head = _("Create EVMS Container");
}
else
{
// popup header
head = _("Modify EVMS Container");
}
}
string txt =
// popup description
_("Change the settings for an EVMS container.
Container type, PE size, and container name can only be set when creating
the container.
");
term dlg =
`HBox(
`HSpacing(2),
`VBox(
`Heading(head),
`Label( txt ),
// label text
`HBox(
`HSpacing(1),
`ComboBox( `id(`type), `opt(`notify), _("Container Type"),
// label text
[ `item( `id("lvm"), _("Linux LVM") ),
// label text
`item( `id("lvm2"), _("Linux LVM2") )] ),
`HSpacing(2),
// label text
`TextEntry( `id(`name), `opt(`notify),
_("Container &Name"), co["name"]:"" ),
`HSpacing(2),
// label text
`TextEntry(`id(`pesize), _("&Physical Extent Size"), ""),
`HSpacing(1)
),
`Left(`HBox(
`HSpacing(1),
`Label( _("Container Size:") ),
`Label( `id(`size), "" ),
`HSpacing(1)
)),
`VSpacing(1),
`HBox(
`HSpacing(2),
`VBox(
`HBox(
`Table(`id(`pv_table), `opt(`notify),
// header text
`header(_("Device"), `Right(_(" Size")),
// header text
_(" Container")),
[] ),
`VSpacing(10)
),
`VSpacing(1),
`HBox(
// button text
`PushButton(`id(`pv_add), _("&Add Volume")),
// button text
`PushButton(`id(`pv_remove), _("&Remove Volume"))
)
),
`HSpacing(2)
),
`VSpacing(1),
`HBox(
// Ok button
`PushButton(`id(`ok), `opt(`default), Label::OKButton() ),
// Cancel button
`PushButton(`id(`cancel), Label::CancelButton() )
),
`VSpacing(0.5)
),
`HSpacing(2)
);
UI::OpenDialog( `opt(`decorated ), dlg );
string name = co["name"]:"";
string typename = co["lvm2"]:false?"lvm2":"lvm";
if( search( name, "aix/" )==0 )
{
typename = "aix";
}
UI::ChangeWidget( `id(`name), `Value, Storage::EvmsShortName(name) );
if( create )
{
UI::ChangeWidget( `id(`name), `ValidChars,
FileSystems::nchars + "-._:" );
}
else
{
UI::ChangeWidget( `id(`name), `Enabled, false );
}
UI::ChangeWidget( `id(`pesize), `Enabled, co["create"]:false );
UI::ChangeWidget( `id(`type), `Enabled, create );
UI::ChangeWidget( `id(`pesize), `Value,
ByteToHumanStringWithZero(co["pesize"]:0 ));
UI::ChangeWidget( `id(`type), `Value, typename );
list<map> pvlist = get_pvlist( tg, co["name"]:"" );
y2milestone( "dlg_modify_container pvlist %1", pvlist );
y2milestone( "dlg_modify_container co %1", co );
set_table_elements( get_table_entries( pvlist, co["name"]:"" ), 0 );
integer cur_size = co["size_k"]:0 * 1024;
set_container_size( co, cur_size );
symbol ret = nil;
repeat
{
ret = (symbol)UI::UserInput();
y2milestone( "dlg_modify_container ret %1", ret );
if( ret == `type )
{
typename = (string)UI::QueryWidget(`id(`type), `Value );
name = typename + "/" + Storage::EvmsShortName(name);
co["name"] = name;
set_table_elements( get_table_entries( pvlist, name ), -1 );
}
else if( ret == `name )
{
name = (string)UI::QueryWidget(`id(`name), `Value );
name = deletechars( name, " \t" );
y2milestone( "dlg_modify_container new name:%1", name );
name = typename + "/" + name;
co["name"] = name;
set_table_elements( get_table_entries( pvlist, name ), -1 );
}
else if( contains( [`pv_add, `pv_remove, `pv_table ], ret ) )
{
integer id = (integer)UI::QueryWidget(`id(`pv_table), `CurrentItem);
if( ret == `pv_table && id != nil )
{
ret = size(pvlist[id,"used_by"]:"")>0?`pv_remove:`pv_add;
}
if( ret == `pv_add && id != nil &&
size(pvlist[id,"used_by"]:"")==0 )
{
name = co["name"]:"";
string dev = "/dev/" + pvlist[id,"device"]:"";
if( size(Storage::GetPartition(tg,dev))==0 )
dev = "/dev/evms/" + pvlist[id,"device"]:"";
y2milestone( "dev:%1", dev );
Storage::SetPartitionMount( dev, "" );
Storage::SetPartitionFormat( dev, false, `none );
Storage::ExtendEvmsCo( old_name, pvlist[id,"device"]:"" );
tg = Storage::GetTargetMap();
co = (map<string,any>)tg["/dev/evms/"+old_name]:$[];
co["name"] = name;
y2milestone( "co: %1", co );
pvlist = get_pvlist( tg, old_name );
cur_size = co["size_k"]:0*1024;
set_container_size( co, cur_size );
set_table_elements( get_table_entries( pvlist, name ), id );
}
else if( ret == `pv_remove && id != nil &&
size(pvlist[id,"used_by"]:"")>0 )
{
name = co["name"]:"";
boolean changed =
Storage::ReduceEvmsCo( old_name, pvlist[id,"device"]:"" );
if( !changed )
{
// message popup
Popup::Error(
_("If you remove the selected partition from the container,
there will not be enough space for all volumes in this container.
To delete the container completely, remove its volumes first."));
}
else
{
tg = Storage::GetTargetMap();
co = (map<string,any>)tg["/dev/evms/"+old_name]:$[];
co["name"] = name;
y2milestone( "co: %1", co );
pvlist = get_pvlist( tg, old_name );
cur_size = co["size_k"]:0*1024;
set_container_size( co, cur_size );
set_table_elements( get_table_entries( pvlist, name ), id );
}
}
}
else if( ret == `ok )
{
co["pesize"] =
evms_pesize_check( (string)UI::QueryWidget( `id(`pesize),
`Value),
typename );
y2milestone( "dlg_modify_container co %1 type %2", co, typename );
if( co["pesize"]:0 == 0 )
{
ret = `again;
}
if( ret==`ok && !evms_check_name(Storage::EvmsShortName(name)) )
{
// error popup text
Popup::Error(_("The data entered is invalid.
Insert a container names like \"system\" or \"test\".
Do not use ;/`, in this name.
"));
ret = `again;
}
if( ret==`ok && co["create"]:false && old_name!=co["name"]:"" &&
(haskey( tg, "/dev/evms/" + co["name"]:"" ) ||
haskey( tg, "/dev/" + name )) )
{
// error popup text
Popup::Error(sformat(_("The container named \"%1\" already exists.
Choose a different name
or cancel this dialog.
"), name ));
ret = `again;
}
if( cur_size <= 0 )
{
// error popup text
Popup::Error(_("The container contains no physical volume.
Every container must consist of at least one physical volume."));
ret = `again;
}
if( old_name!=co["name"]:"" || old_pesize!=co["pesize"]:0 )
{
name = co["name"]:"";
y2milestone( "name old:%1 new:%2 pe old:%3 new:%4",
old_name, name, old_pesize, co["pesize"]:0 );
Storage::ModifyEvmsCo( old_name, Storage::EvmsShortName(name),
co["pesize"]:0,
search(name,"lvm2/")==0 );
}
}
} until( ret == `ok || ret == `cancel );
UI::CloseDialog();
map r = $["ok":false];
if (ret == `ok )
{
r["ok"] = true;
r["name"] = co["name"]:"";
y2milestone( "dlg_modify_container ret co %1", co );
}
y2milestone( "dlg_modify_container ret ok %1", r["ok"]:false );
return( r );
};
define map add_evms_container( map<string,map> tg )
``{
map ret = $[ "ok":false ];
string name = "";
list<string> l = maplist( string k, map entry,
filter( string key, map e, tg,
``(e["type"]:`CT_UNKNOWN==`CT_EVMS &&
size(e["name"]:"")>0)),
``(entry["name"]:""));
y2milestone( "add_evms_container l:%1", l );
if( size(l)==0 )
name = "lvm2/system";
else
{
integer num = size(l)+1;
name = sformat( "lvm2/co%1", num );
while( size(filter( string s, l,
``{
integer ret=search(s,substring(name,4));
return( ret!=nil && ret>0 );
}
))>0 )
{
num = num+1;
name = sformat( "lvm2/co%1", num );
}
}
map<string,any> co =
$[ "size_k" : 0,
"pesize" : 4 * 1024 * 1024,
"create" : true,
"type" : `CT_EVMS,
"is_container" : true,
"name" : name,
"lvm2" : true,
"partitions" : []
];
if( Storage::CreateEvmsCo( co["name"]:"", co["pesize"]:1024,
co["lvm2"]:false ))
{
ret = dlg_modify_container( tg, co, true );
if( !ret["ok"]:false )
{
Storage::DeleteEvmsCo( co["name"]:"" );
}
}
y2milestone( "add_evms_container ret:%1", ret );
return( ret );
};
define map edit_evms_container( map<string,map> tg, string key )
``{
map ret = $[ "ok":false ];
y2milestone( "edit_evms_container key %1", key );
map<string,any> co = (map<string,any>)tg["/dev/evms/"+key]:$[];
co["name"] = key;
ret = dlg_modify_container( tg, co, false );
y2milestone( "edit_evms_container ret:%1", ret );
return( ret );
};
define map remove_evms_container( map<string,map> tg, string key )
``{
y2milestone( "remove_evms_container key %1", key );
string mkey = "/dev/evms/"+key;
map ret = $["ok":false];
map co = tg[mkey]:$[];
if( size(co["partitions"]:[])>0 )
{
// Message popup
Popup::Message(sformat(
_("The container \"%1\" contains at least one volume.
It cannot be removed. Remove all volumes of this container
before removing the container"), key ));
}
else
{
// popup text
if( Popup::ContinueCancel( sformat( _("Really remove container \"%1\"?"), key)))
{
Storage::DeleteEvmsCo( co["name"]:"" );
ret["ok"] = true;
}
}
y2milestone( "remove_evms_container ret:%1", ret );
return( ret );
}
//////////////////////////////////////////////////////////////////////
// show a new list of containers
//////////////////////////////////////////////////////////////////////
define void new_co_list( list co_list )
``{
UI::ReplaceWidget(`id(`rcont), `ComboBox(`id(`cont), `opt(`notify),
// button text
_("EVMS &Container"), co_list ));
};
define integer get_co_size( map co )
``{
integer sum_byte = co["size_k"]:0 * 1024;
return( sum_byte );
}
define void new_co_size( map co )
``{
integer total = get_co_size(co);
integer free = co["pe_free"]:0 * co["pesize"]:0;
y2milestone( "total %1 free %2", total, free );
string total_s = ByteToHumanStringWithZero( total );
string free_s = ByteToHumanStringWithZero( free );
UI::ChangeWidget( `id(`co_size), `Value, total_s );
UI::ChangeWidget( `id(`co_free), `Value, free_s );
if( UI::WidgetExists( `id(`co_graph)) )
{
UI::ChangeWidget( `id(`co_graph), `Labels,
// e.g. %1 is replaced with a size e.g.. "used 5 GB"
[ sformat( _("used\n%1"),
ByteToHumanStringWithZero(total-free)),
// e.g. %1 is replaced with a size e.g.. "free 1 GB"
sformat( _("free\n%1"), free_s ) ] );
UI::ChangeWidget( `id(`co_graph), `Values, [ (total-free)/1024/1024,
free/1024/1024 ] );
}
UI::RecalcLayout();
}
define term get_bargraph_if_possible()
``{
term ret = `Empty();
if( UI::HasSpecialWidget( `BarGraph ))
{
ret = `Left(`BarGraph( `id(`co_graph), `opt(`hstretch),
[ 0, 10 ], [ "", ""]) );
}
y2milestone( "get_bargraph_if_possible ret %1", ret );
return( ret );
};
define map get_co_map( string current, map tg )
``{
return( tg["/dev/evms/"+current]:$[] );
}
define list get_containers( map<string,map> tg, string none )
``{
list ret = [];
foreach( string k, map e, tg,
``{
if( e["is_container"]:false )
{
ret = add( ret, substring( k, 10 ));
}
});
if( size(ret)==0 )
{
ret = [ none ];
}
y2milestone( "get_containers ret %1", ret );
return( ret );
}
define list get_evms_volumes( map<string,map> tg )
``{
list<string> tmp = [];
foreach( string k, map e, tg,
``{
if( search( k, "/dev/evms" )==0 && !e["is_container"]:false )
{
tmp = add( tmp, k );
foreach( map p, e["partitions"]:[], ``(y2milestone( "get_evms_volumes p:%1", p )));
}
});
list<string> keys = sort( tmp );
tmp = [];
foreach( string k, map e, tg,
``{
if( search( k, "/dev/evms" )==0 && e["is_container"]:false )
{
tmp = add( tmp, k );
foreach( map p, e["partitions"]:[], ``(y2milestone( "p:%1", p )));
}
});
keys = (list<string>)merge( keys, sort(tmp) );
list<map> parts = [];
y2milestone( "get_evms_volumes keys %1", keys );
foreach( string k, keys,
``{
list<map> pa =
filter( map p, tg[k,"partitions"]:[],
``(p["used_by_type"]:`UB_NONE==`UB_NONE));
pa = filter( map p, pa,
``{
string ndev = evms_dev_disk( p["device"]:"" );
return( !Storage::IsRealDisk( tg[ndev]:$[] ));
});
pa = filter_deleted_parts( tg, pa );
if( k=="/dev/evms" )
{
pa = filter_mounted_evms_part( tg, pa );
}
parts =
(list<map>)merge( parts,
sort( map x, map y, pa,
``(x["name"]:(any)""<y["name"]:(any)"")));
});
y2milestone( "get_evms_volumes parts %1", parts );
list ret = maplist( map p, parts,
``{
string fo = "";
if( p[`enc_type]:`none != `none )
{
fo = fo + "C";
}
if( p["format"]:false )
{
fo = fo + "F";
}
return( `item( `id(p["device"]:""),
p["device"]:"",
ByteToHumanStringWithZero(p["size_k"]:0*1024), fo,
p["mount"]:"",
p["evms_native"]:false?"N":"C"
));
});
y2milestone( "get_evms_volumes ret %1", ret );
return( ret );
}
define void volume_handle_max( integer stripe, string max_text )
``{
y2milestone( "volume_handle_max stripe %1", stripe );
UI::ChangeWidget( `id(`max_size), `Enabled, stripe==1 );
UI::ChangeWidget( `id(`max_text), `Value, stripe==1?max_text:"" );
}
define map<string,any> dlg_logical_volume( map<string,any> co,
map<string,any> part,
boolean create, boolean is_cont )
``{
y2milestone( "dlg_logical_volume create:%1 p=%2 container:%3",
create, part, is_cont );
y2milestone( "dlg_logical_volume co:%1",
filter(string k, any e, co, ``(k!="partitions")) );
integer new_size = part["size_k"]:0 * 1024;
integer old_size = new_size;
if( haskey( part, "orig_size_k" ))
old_size = part["orig_size_k"]:0*1024;
integer max_size = co["pe_free"]:0 * co["pesize"]:0;
if( !create )
{
max_size = max_size + new_size;
}
string curr_size = ByteToHumanStringWithZero(new_size);
old_size = kmgt_str_to_byte(curr_size);
string vol_name = part["name"]:"";
integer stripes = part["stripes"]:1;
integer stripesize = part["stripesize"]:64;
integer pesize = co["pesize"]:1;
string mkey = "/dev/evms";
if( is_cont )
{
mkey = mkey + "/" + co["name"]:"";
}
y2milestone( "dlg_logical_volume mkey %1 vol_name %2", mkey, vol_name );
list stripes_poss = [
`item(`id(1), "1", stripes == 1 ),
`item(`id(2), "2", stripes == 2 ),
`item(`id(3), "3", stripes == 3 ),
`item(`id(4), "4", stripes == 4 ),
`item(`id(5), "5", stripes == 5 ),
`item(`id(6), "6", stripes == 6 ),
`item(`id(7), "7", stripes == 7 ),
`item(`id(8), "8", stripes == 8 )
];
list stripe_size = [
`item(`id(4), "4", stripesize == 4 ),
`item(`id(8), "8", stripesize == 8 ),
`item(`id(16), "16", stripesize == 16 ),
`item(`id(32), "32", stripesize == 32 ),
`item(`id(64), "64", stripesize == 64 ),
`item(`id(128), "128", stripesize == 128 ),
`item(`id(256), "256", stripesize == 256 ),
`item(`id(512), "512", stripesize == 512 ),
];
string heading = "";
boolean is_create_mode = false;
boolean is_resize_mode = false;
boolean is_mount_mode = false;
term ui_vol_name = `Empty();
// header for input field size of volume
string size_txt = sformat(_("&Size: (e.g., %1 %2)"),
ByteToHumanStringWithZero(4196*1024*1024),
ByteToHumanStringWithZero(210*1024*1024));
// header for input field maximum allowd size
string max_text = sformat(_("max = %1 "),
ByteToHumanStringWithZero(max_size));
if( create && part["create"]:false )
{
// popup heading
heading = _("Create Logical Volume");
is_create_mode = true;
}
else if( !create && part["create"]:false )
{
// popup heading
heading = _("Edit Logical Volume");
is_create_mode = false;
}
else
{
// popup heading
if( is_cont )
{
heading = _("Resize Logical Volume");
}
else
{
heading = _("Edit Logical Volume");
}
is_create_mode = false;
is_resize_mode = is_cont;
is_mount_mode = !is_resize_mode;
stripes_poss = [ `item(`id(1), "-", true) ];
stripe_size = [ `item(`id(1), "-", true) ];
}
if( is_create_mode )
{
ui_vol_name = `VBox( `TextEntry(`id(`vol_name),
// label text
_("Volume &Name "), vol_name),
// label text
`Left(`Label(_("(e.g. var, opt)")))
);
}
else
{
// display name of current volume group
ui_vol_name = `VBox( `Label(""),
// label text
`HBox(`Label( _("Volume Name: ")),
`Heading(`opt(`outputField), vol_name ),
`HStretch()
));
}
term evms_specials = `Empty();
if( !is_mount_mode )
{
evms_specials = `VBox(
`Top(`Left(ui_vol_name)),
`Top(`VBox(
`TextEntry(`id(`size), size_txt, curr_size),
`HBox(
// set size to maxsize
`Left(`Label( `id(`max_text), max_text )),
// button text
`PushButton( `id(`max_size), _("ma&x")))
)),
`VStretch(),
`Left(`ComboBox( `id(`stripes), `opt(`hstretch,`notify),
// button text
_("Stri&pes"), stripes_poss )),
`VStretch(),
`Left(`ComboBox( `id(`stripesize), `opt(`hstretch,`notify),
// button text
_("Stripe &Size"), stripe_size )),
`VStretch());
}
else
{
// label text %1 is prelaced by e.g. 4 GB
string txt = sformat( _("Size %1"), curr_size );
evms_specials = `VBox( `Right( `Label( txt ) ) );
}
y2milestone( "dlg_logical_volume is_create_mode %1 is_resize_mode %2 is_mount_mode %3",
is_create_mode, is_resize_mode, is_mount_mode );
map<symbol,map> fs = FileSystems::GetAllFileSystems(true, true);
UI::OpenDialog(
`opt(`decorated ),
`HBox(`HWeight(30,
`HBox(
`HSpacing(1),
`HStretch(),
`VBox(
`Heading(heading),
`VStretch(),
`VSpacing(1),
`HBox(
`HWeight( 40, FormatDlg( part, fs )),
`HStretch(),
`HSpacing(0.5),
`HWeight( 40, `VBox(
`Top(evms_specials),
`VSpacing(1),
`ReplacePoint( `id(`mount_dlg_rp),
MountDlg(part, []))
))
),
`VStretch(),
`VSpacing(1),
`HBox(
// Ok button
`PushButton( `id(`ok), `opt(`default),
Label::OKButton() ),
// Cancel button
`PushButton( `id(`cancel), Label::CancelButton() )
)
),
`HStretch(),
`HSpacing(1)
)
)));
// configure main dialog for the first call
if( is_create_mode )
{
UI::ChangeWidget( `id(`vol_name), `ValidChars,
FileSystems::nchars + "-._:" );
}
if( !is_mount_mode )
{
UI::ChangeWidget( `id(`stripes), `Enabled, !is_resize_mode );
UI::ChangeWidget( `id(`stripesize), `Enabled,
!is_resize_mode && stripes>1 );
volume_handle_max( stripes, max_text );
}
////////////////////////////////////////////////////////////////////
// User mainloop for dialog
////////////////////////////////////////////////////////////////////
boolean input_is_ok = true;
map<string,any> retval = part;
retval = HandlePartWidgetChanges( true, `ok, fs, part, retval );
any ret = `cancel;
repeat
{
input_is_ok = true;
ret = UI::UserInput();
y2milestone( "dlg_logical_volume ret %1", ret );
/////////////////////////////////////////////////////////
if( ret == `stripes)
{
stripes = (integer)UI::QueryWidget( `id(`stripes), `Value);
UI::ChangeWidget( `id(`stripesize), `Enabled,
!is_resize_mode && stripes>1 );
volume_handle_max( stripes, max_text );
continue;
}
if( ret == `max_size)
{
UI::ChangeWidget( `id(`size), `Value,
ByteToHumanStringWithZero(max_size));
continue;
}
if( ret != `cancel )
{
retval = HandlePartWidgetChanges( false, ret, fs, part, retval );
}
if( is_create_mode )
{
vol_name = (string)UI::QueryWidget( `id(`vol_name), `Value );
vol_name = deletechars( vol_name, " \t" );
}
if( UI::WidgetExists( `id(`stripes) ))
{
stripes = (integer)UI::QueryWidget(`id(`stripes), `Value);
stripesize = (integer)UI::QueryWidget(`id(`stripesize), `Value);
}
if( ret==`ok )
{
if( UI::WidgetExists( `id(`size) ))
{
new_size =
kmgt_str_to_byte( (string)UI::QueryWidget(`id(`size),
`Value));
if( !check_max_size(new_size, max_size) )
{
input_is_ok = false;
continue;
}
if( !check_ok_fssize(new_size, retval) )
{
input_is_ok = false;
continue;
}
y2milestone( "dlg_logical_volume new_size %1 old_size %2",
new_size, old_size );
}
if( is_resize_mode && !retval["format"]:false &&
new_size!=old_size )
{
string mp = retval["inactive"]:false ? "" : retval["mount"]:"";
if( !CheckResizePossible( true, true, new_size-old_size,
retval["used_fs"]:`unknown, mp ))
{
UI::ChangeWidget(`id(`size), `Value, curr_size );
continue;
}
}
if( is_create_mode )
{
if( !evms_check_name(vol_name) )
{
input_is_ok = false;
// error popup text
// xgettext:no-c-format
Popup::Error(_("Check your volume name.
Use names like \"opt\" or \"var\" ...
Do not use ;/\`',!\"%#"));
UI::SetFocus(`id(vol_name));
continue;
}
else
{
list names = maplist( map p, co["partitions"]:[],
``(p["name"]:""));
if( contains( names, vol_name ) )
{
input_is_ok = false;
// error popup text
Popup::Error(sformat(_("A volume named \"%1\" already exists
in container \"%2\". Choose another name
or cancel this dialog.
"), vol_name, co["name"]:"" ));
UI::SetFocus(`id(vol_name));
continue;
}
}
}
map ret_mp = CheckOkMount( mkey+"/"+vol_name, part, retval );
retval = ret_mp["map"]:$[];
if( !ret_mp["ok"]:false )
{
if( ret_mp["field"]:`none != `none )
UI::SetFocus(`id( ret_mp["field"]:`none ));
input_is_ok = false;
continue;
}
y2milestone( "dlg_logical_volume retval %1 Doit:%2",
retval["mount"]:"", Storage::DoCheckEvmsNonEvms );
if( size(retval["mount"]:"")>0 && Storage::DoCheckEvmsNonEvms )
{
map<string,map> tg = Storage::GetTargetMap();
list<string> ud = Storage::GetUsedRealDisksNew( tg, true );
list<string> dl = Storage::GetEvmsRealDisk( tg, part );
list isc = filter( string d, dl, ``(contains( ud, d )));
if( size(isc)>0 )
{
if( !Popup::YesNo( evms_texts_evms_nonevms() ))
{
input_is_ok = false;
continue;
}
else
{
Storage::DoCheckEvmsNonEvms = false;
}
}
}
ret_mp = CheckDeviceFinalOk( retval );
if( !ret_mp["ok"]:false )
input_is_ok = false;
else
retval = ret_mp["map"]:$[];
}
/////////////////////////////////////////////////////////
retval["stripes"] = stripes;
if( stripes>1 )
{
retval["stripesize"] = stripesize;
}
if( !is_mount_mode )
{
retval["name"] = vol_name;
retval["device"] = mkey + "/" + vol_name;
if( new_size != old_size )
retval["size_k"] = (((new_size+pesize-1)/pesize)*pesize)/1024;
y2milestone( "dlg_logical_volume size_k %1 new_size %2 old %3",
retval["size_k"]:-1, new_size, old_size );
}
}
until ( (ret==`ok&&input_is_ok) || ret == `cancel );
UI::CloseDialog();
if( ret == `cancel || !input_is_ok )
{
retval = $[];
}
y2milestone( "dlg_logical_volume retval=%1", retval );
return( retval );
};
define map add_evms_volume( string co_name, map<string,map> tg )
``{
y2milestone( "add_evms_volume co_name %1", co_name );
map ret = $[ "ok" : false ];
map<string,any> part =
$[ "create" : true,
"used_fs" : Partitions::DefaultFs(),
"stripes" : 1,
"format" : true,
"type" : `evms,
"fstype" : "EVMS",
"mount" : GetMountPointProposal( tg, [ Partitions::BootMount() ] )
];
map<string,any> co = (map<string,any>)tg["/dev/evms/"+co_name]:$[];
if( co["pe_free"]:0==0 )
{
// popup text %1 is replaced by a container name
Popup::Message(sformat(_("There is no available space in the current container %1."), co_name ));
}
else
{
co["name"] = co_name;
part["size_k"] = co["pe_free"]:0/4 * co["pesize"]:0 / 1024;
part = dlg_logical_volume( co, part, true, true );
if( size(part)>0 )
{
ret["ok"] = Storage::CreateEvmsVolume( co_name, part["name"]:"",
part["size_k"]:0,
part["stripes"]:1 );
if( !ret["ok"]:false )
{
string txt = _("A volume with the requested size
could not be created.
");
if( part["stripes"]:1 > 1 )
txt = txt + _("Try reducing the stripe count of the volume.");
Popup::Error( txt );
}
else
{
ret["ok"] = Storage::ChangeVolumeProperties( part );
if( ret["ok"]:false && part["stripes"]:1>1 &&
part["stripesize"]:0>0 )
ret["ok"] = Storage::ChangeEvmsStripeSize( co_name,
part["name"]:"",
part["stripesize"]:0 );
}
}
}
y2milestone( "add_evms_volume ret=%1", ret );
return( ret );
};
define map edit_evms_volume( string device, map<string,map> tg )
``{
y2milestone( "edit_evms_volume device %1", device );
map ret = $[ "ok" : false ];
map d = Storage::GetDiskPartition( device );
y2milestone( "edit_evms_volume d %1", d );
string key = d["disk"]:"";
if( !haskey( tg, key ) )
{
key = "/dev/evms";
}
y2milestone( "edit_evms_volume key %1", key );
map<string,any> part = Storage::GetPartition( tg, device );
y2milestone( "edit_evms_volume part %1", part );
integer last_size = part["size_k"]:0*1024;
part = dlg_logical_volume( (map<string,any>)tg[key]:$[], part, false,
tg[key,"is_container"]:false );
if( size(part)>0 )
{
ret["ok"] = Storage::ChangeVolumeProperties( part );
if( ret["ok"]:false && last_size != part["size_k"]:0*1024 )
ret["ok"] = Storage::ResizeVolume( part["device"]:"", key,
part["size_k"]:0 );
}
return( ret );
};
define map delete_evms_volume( string device, map<string,map> tg )
``{
y2milestone( "delete_evms_volume device %1", device );
map ret = $[ "ok" : false ];
map d = Storage::GetDiskPartition( device );
string key = d["disk"]:"";
if( !haskey( tg, key ) )
{
key = "/dev/evms";
}
map<string,any> part = Storage::GetPartition( tg, device );
y2milestone( "delete_evms_volume part %1", part );
if( !tg[key,"is_container"]:false )
{
// popup text %1 is replaced by a container name
Popup::Message(sformat(_("You can only delete logical volumes in a container.
%1 is not a logical volume produced by a container.
"), device ));
}
else if( check_device_delete( part, false, Mode::installation() ))
{
string txt = sformat( _("Really delete %1?"), part["device"]:"" );
if( Popup::YesNo( txt ) )
{
ret["ok"] = Storage::DeleteDevice( key, part["device"]:"" );
}
}
return( ret );
};
}