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
/
modules
/
AutoinstLVM.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
20KB
|
502 lines
/**
* File: modules/AutoinstLVM.ycp
* Module: Auto-Installation
* Summary: LVM
* Authors: Anas Nashif <nashif@suse.de>
*
* $Id: AutoinstLVM.ycp 32415 2006-08-17 15:06:17Z ug $
*/
{
module "AutoinstLVM";
textdomain "autoinst";
import "Storage";
import "Report";
import "Partitions";
import "FileSystems";
import "AutoinstStorage";
import "Label";
include "partitioning/lvm_pv_lib.ycp";
include "partitioning/lvm_lib.ycp";
include "partitioning/lvm_lv_lib.ycp";
include "partitioning/partition_defines.ycp";
global symbol vmType = `CT_LVM;
global boolean ZeroNewPartitions = true;
global map<string, map> ExistingLVM = $[];
global list<string> ExistingVGs = [];
// LVM map as imported from Profile
global map<string, map> lvm = $[];
// useless
// boolean pvs_on_unconfigured = false;
// temporary copy of variable from Storage
// map <string, map> targetMap = $[];
// temporary copy of variable from Storage
map<string, map> targetMap = $[];
boolean old_available = false;
/**
* Constructer
*/
global define void AutoinstLVM() {
return;
}
/**
* Initialize
* @return void
*/
global define boolean Init () {
y2milestone("entering Init");
y2milestone("AutoTargetMap is %1",AutoinstStorage::AutoTargetMap);
lvm = filter(string k, map v,
AutoinstStorage::AutoTargetMap, ``(v["type"]:`CT_UNKNOWN==`CT_LVM));
// either LVM or EVMS is allowed.
if (size(lvm) == 0) {
lvm = filter(string k, map v,
AutoinstStorage::AutoTargetMap, ``(v["type"]:`CT_UNKNOWN==`CT_EVMS));
if (size(lvm) == 0) {
// no LVM and no EVMS is wanted. We can go now.
return false;
}
vmType = `CT_EVMS;
}
// check for existing VM
targetMap = Storage::GetTargetMap();
y2milestone("GetTargetMap returns %1",targetMap);
//ExistingLVM = filter(string k, map v, Storage::GetTargetMap(), ``(v["type"]:`CT_UNKNOWN==`CT_LVM));
ExistingLVM = filter(string k, map v, Storage::GetTargetMap(), ``(v["type"]:`CT_UNKNOWN==vmType));
ExistingVGs = maplist (string d, map g, ExistingLVM, ``{
return (substring(d, 5) );
});
y2milestone("Existing VGs: %1", ExistingVGs );
y2milestone("Existing LVM: %1", ExistingLVM);
symbol dropType = ( vmType == `CT_LVM ? `CT_EVMS : `CT_LVM );
// if we want to create EVMS, drop all existing LVMs now
// and vice versa
// it's not possible to mix LVM and EVMS with autoyast
//
map<string, map> toDrop = filter(string k, map v, Storage::GetTargetMap(), ``(v["type"]:`CT_UNKNOWN==dropType));
foreach (string device, map volume_group, toDrop , ``{
string vgname = substring(device, 5);
y2milestone("removing %1 %2",dropType,vgname);
removeVolumeGroup(vgname); // FIXME: I expect this to work recursive
});
// FIXME
foreach (string v, ExistingVGs, ``{
string dev = sformat("/dev/%1", v);
if (size(ExistingLVM[dev,"partitions"]:[]) > 0 ) {
old_available = true;
}
});
// Process data
lvm = mapmap(string device, map disk, lvm, ``{
foreach( string key, ["keep_lv"], ``{
list num = [];
list<string> nlist = splitstring(disk[key]:"", ",");
foreach( string n, nlist, ``{
num = union( num, [n] );
});
disk[key] = num;
});
list fsys = [];
list<string> nlist = splitstring( disk["keep_lv_fsys"]:"" , "," );
foreach( string n, nlist, ``{
symbol fs = FileSystems::FsToSymbol(n);
if( fs != `none ) {
fsys = union( fsys, [ fs ] );
}
});
disk["keep_lv_fsys"] = fsys;
disk["pesize"] = pesize_str_to_byte(disk["pesize"]:"4M");
string vgname = substring(device, 5);
disk["partitions"] = maplist(map lv, disk["partitions"]:[], ``{
string lvsize_str = lv["size"]:"";
string mount_point = lv["mount"]:"";
integer lvsize = 0;
// useless? maybe a sideeffect is wanted
// list<map> parts = get_possible_pvs( Storage::GetTargetMap() );
integer vgsize = targetMap[device,"size_k"]:0*1024;
if (lvsize_str == "auto" && mount_point == "swap") {
y2milestone("swap slot size: %1", vgsize/1024*1024 );
lvsize = 1024*1024*Partitions::SwapSizeMb(vgsize/(1024*1024));
} else if (lvsize_str!= "") {
lvsize = kmgt_str_to_byte(lvsize_str);
}
lv["size_k"] = lvsize/1024;
if( vmType == `CT_LVM ) {
lv["type"] = `lvm;
} else if( vmType == `CT_EVMS ) {
lv["type"] = `evms;
lv["evms_name"] = lv["lv_name"]:"";
}
lv["name"] = lv["lv_name"]:"";
return(lv);
});
return($[device:disk]);
});
return true;
}
/**
* Delete possible partitions
*/
define boolean remove_possible_volumes(string vgname) {
y2milestone("Deleting possible VGs and LVs");
if (ExistingLVM == $[])
return true;
map vg = ExistingLVM["/dev/" +vgname]:$[];
list<map> lvs = vg["partitions"]:[];
y2milestone("Existing LVs: %1", lvs);
foreach(map lv, lvs, ``{
if (!contains(lvm["/dev/"+vgname, "keep_lv"]:[], lv["name"]:"")) {
removeLogicalVolume( "/dev/"+vgname,
"/dev/"+vgname+"/"+lv["name"]:"" ); //FIXME: does removeLogicalVolume work for EVMS?
}
});
if (size(lvm["/dev/"+vgname, "keep_lv"]:[]) == 0 &&
ExistingLVM["/dev/" +vgname]:$[] != $[]) {
removeVolumeGroup( vgname ); //FIXME: does removeVolumeGroup work for EVMS?
}
return true;
}
/**
* Keep logical volume
* @param string volume group name
* @param string logical volume
* @return void
*/
/* FIXME: this looks useless to me.
global define map KeepLV (string vgname, map lv, map<string,map> targetMap ) {
y2milestone("entering KeepLV with %1 - %2 - %3",vgname,lv,targetMap);
map modLV = $[
"create" : false,
"region" : lv["region"]:[],
"fsid" : 142, //FIXME: EVMS?
"fstype" : "LV", //FIXME: EVMS?
"nr" : lv["nr"]:"",
"mount" : lv["mount"]:"" ,
"used_fs" : lv["used_fs"]:`reiser,
"format" : lv["format"]:false ,
"type" : `lvm, //FIXME: EVMS?
"device" : "/dev/" + vgname + "/" + lv["nr"]:""
];
return( $[ "targets":Storage::SetPartition( targetMap, modLV ) ]);
}
*/
/**
* Return only those PVs on disks touched by the control file, dont add PVs of
* unconfigured disks.
* @param string volume group name
* @return list existing PVs
*/
global define list<map> get_existing_pvs ( string vgname ) {
y2milestone("entering get_existing_pvs with %1",vgname);
map<string, map> tm = $[];
symbol usedBy = `UB_LVM;
foreach(string k, map v, AutoinstStorage::AutoTargetMap, ``{
// if (Storage::IsRealDisk( v ))
y2milestone("AutoTargetMap = %1", v );
// FIXME: how about v["type"]:`CT_UNKNOWN == `CT_DISK
if ( v["type"]:`CT_UNKNOWN != `CT_LVM && v["type"]:`CT_UNKNOWN != `CT_EVMS) {
tm[k] = v;
integer i = 0;
foreach( map p, v["partitions"]:[], ``{
if( haskey(p,"lvm_group") ) {
tm[k,"partitions",i,"used_by_type"] = `UB_LVM;
tm[k,"partitions",i,"used_by"] = p["lvm_group"]:"";
} else if( haskey(p,"evms_group") ) {
tm[k,"partitions",i,"used_by_type"] = `UB_EVMS;
tm[k,"partitions",i,"used_by"] = p["evms_group"]:"";
usedBy = `UB_EVMS;
}
i = i + 1;
});
} else if (k == "/dev/md") {
// FIXME: will this ever be reached?
tm[k] = v;
}
});
y2milestone("tm: %1", tm);
// all possible PVs on all available devices
list<map> all_possible_pvs = filter( map part, get_possible_pvs( Storage::GetTargetMap() ),
``( ((part["used_by"]:"" == vgname && part["used_by_type"]:`UB_NONE == usedBy ) ||
part["used_by_type"]:`UB_NONE == `UB_NONE) && !part["delete"]:false ));
y2milestone("all pvs= %1", all_possible_pvs);
// FIXME
return (all_possible_pvs);
}
/**
* Return list of deleted PVS
* @param string volume group name
* @return list<map> list of deleted PVs
*/
/* FIXME: useless?
global define list<map> get_deleted_pvs ( string vgname ) {
y2milestone("entering get_deleted_pvs with %1",vgname);
list<list<map> > ret = [];
foreach( string dev, map devmap, Storage::GetTargetMap(),
``{
ret = add( ret,
filter( map part, devmap["partitions"]:[],
``(
part["lvm_group"]:"" == vgname &&
part["delete"]:false &&
( part["fsid"]:0 == Partitions::fsid_lvm ||
part["fsid"]:0 == Partitions::fsid_raid ||
part["fsid"]:0 == Partitions::fsid_native )
)
)
);
});
y2milestone("deleted PVs: %1", flatten(ret) );
return( flatten(ret) );
}
*/
/**
* Write LVM Configuration
* @return boolean true on success
*/
global define boolean Write () {
y2milestone("entering Write");
Storage::SetZeroNewPartitions(ZeroNewPartitions);
list lvm_vgs = get_vgs( targetMap ); // FIXME: does not work for EVMS
string current_vg = "";
boolean error = false;
foreach (string device, map volume_group, lvm , ``{
y2milestone("volume_group is %1", volume_group);
string use = volume_group["use"]:"none";
boolean lvm2 = volume_group["lvm2"]:true;
string lvm_string = lvm2 ? "lvm2" : "lvm";
string vgname = substring(device, 5);
current_vg = vgname;
list<map> new_pvs = get_existing_pvs(vgname);
if (volume_group["prefer_remove"]:false) {
remove_possible_volumes(vgname);
}
map vg = $[];
if (size(volume_group["keep_lv"]:[]) == 0 ) {
vg["vgname"] = vgname;
vg["pesize"] = volume_group["pesize"]:1;
vg["lvm2"] = lvm2;
map addVG = $[];
if( vmType == `CT_LVM ) {
addVG = addVolumeGroup(vg, targetMap, [] );
current_vg = addVG["vg"]:"none";
y2milestone("addVolumeGroup returns %1",addVG);
} else if( vmType == `CT_EVMS ) {
Storage::CreateEvmsCo( lvm_string + "/" + vgname, vg["pesize"]:1024,vg["lvm2"]:false );
current_vg = addVG["vg"]:"none";
y2milestone("add_evms_volume returns %1",addVG);
}
targetMap = Storage::GetTargetMap();
y2milestone("Storage::GetTargetMap returns %1",targetMap);
lvm_vgs = get_vgs( targetMap );
}
list<string> new_pvs_devices= maplist(map pv, new_pvs, ``{
return(pv["device"]:"");
});
y2milestone("Existing PVs: %1", new_pvs );
map atm = AutoinstStorage::AutoTargetMap;
foreach(map pv, new_pvs, ``{
if (pv["create"]:false) {
boolean to_add = true;
if( vmType == `CT_LVM ) {
// exclude partitions that are NOT supposed to be in the LVM
foreach( map atm_vol, atm[pv["maindev"]:"","partitions"]:[], ``{
if( pv["nr"]:0 == atm_vol["partition_nr"]:-1 ) {
if( atm_vol["lvm_group"]:"" != current_vg ) {
y2milestone("do not add %1",atm_vol);
to_add = false;
}
}
});
if( to_add ) {
y2milestone("addPhysicalVolume %1 , %2",pv["device"]:"", current_vg );
addPhysicalVolume(targetMap, pv["device"]:"", current_vg );
}
} else if( vmType == `CT_EVMS ) {
// exclude partitions that are NOT supposed to be in the EVMS
foreach( map atm_vol, atm[pv["maindev"]:"","partitions"]:[], ``{
if( pv["nr"]:0 == atm_vol["partition_nr"]:-1 ) {
if( atm_vol["evms_group"]:"" != current_vg ) {
y2milestone("do not add %1",atm_vol);
to_add = false;
}
}
});
if( to_add ) {
y2milestone("Storage::ExtendEvmsCo %1/%2",lvm_string,pv["device"]:"");
Storage::ExtendEvmsCo(lvm_string+"/"+vgname, pv["device"]:"");
}
}
}
});
// calculating the "max" for logical volume
map<string, map> tmp_tm = Storage::GetTargetMap();
integer freeSpace = 0;
integer buffer = 0;
if( vmType == `CT_LVM ) {
freeSpace = tmp_tm[device,"size_k"]:0;
buffer = tmp_tm[device,"cyl_size"]:0;
} else if( vmType == `CT_EVMS ) {
freeSpace = tmp_tm[ "/dev/evms/"+lvm_string+"/"+vgname, "size_k"]:0;
buffer = tmp_tm[ "/dev/evms/"+lvm_string+"/"+vgname, "cyl_size"]:0;
}
buffer = (buffer * 2) / 1024;
volume_group["partitions"] = maplist( map lv, volume_group["partitions"]:[], ``{
integer s = kmgt_str_to_byte( lv["size"]:"10000" );
if( s <= 100 && s > 0 ) {
// we assume percentage for this lv
integer integer_k = freeSpace * tointeger(lv["size"]:"0") / 100;
lv["size_k"] = integer_k;
y2milestone("percentage for lv %1. Size_k is %2",lv,integer_k);
}
return lv;
});
foreach(map lv, volume_group["partitions"]:[], ``{
freeSpace = freeSpace - lv["size_k"]:0;
y2milestone("freeSpace = %1",freeSpace);
});
freeSpace = freeSpace - buffer; // that's a buffer for rounding errors with cylinder boundaries
foreach(map lv, volume_group["partitions"]:[], ``{
if( lv["size_k"]:0 == 0 && freeSpace > 0 ) {
// if "max" calculation is turned on for the LV
lv["size_k"] = freeSpace;
lv["size"] = sformat("%1K",freeSpace);
}
list<map> lvlist = ExistingLVM[device, "partitions"]:[];
if (contains(volume_group["keep_lv"]:[], lv["nr"]:"_error_")) {
list<map> lvtokeep = filter(map p, lvlist, ``(p["nr"]:"" == lv["lv_name"]:""));
map this_lv = lvtokeep[0]:$[];
y2milestone("Keeping LV: %1", this_lv);
lv["used_fs"] = this_lv["used_fs"]:`reiser;
map lvret = $[];
if (lv["resize"]:false ) {
map reslv = $[
"create" : false,
"region" : lv["region"]:[],
"fsid" : 142,
"lv_size" : lv["lv_size"]:0,
"fstype" : "LV",
"nr" : lv["nr"]:"",
"mount" : lv["mount"]:"" ,
"used_fs" : this_lv["used_fs"]:`reiser,
"format" : lv["format"]:false ,
"type" : `lvm,
"device" : "/dev/" + current_vg + "/" + lv["name"]:""
];
reslv["changed_size"] = true;
Storage::ResizeVolume( "/dev/" + current_vg + "/" + lv["name"]:"",
"/dev/" + current_vg,
lv["lv_size"]:0/1024 );
} else {
Storage::ChangeVolumeProperties( lv );
}
targetMap = lvret["targets"]:targetMap;
} else if ( lv["create"]:true ) {
lv["used_fs"] = lv["filesystem"]:`reiser;
lv["create"] = true;
lv["format"] = lv["format"]:true;
if( vmType == `CT_LVM ) {
lv["device"] = "/dev/" + current_vg + "/" + lv["name"]:"";
} else if( vmType == `CT_EVMS ) {
// FIXME: is lv["device"] needed at all here?
lv["device"] = "/dev/evms/"+lvm_string+"/"+vgname+"/"+lv["name"]:"";
}
if( vmType == `CT_LVM ) {
addLogicalVolume(lv, current_vg); // FIXME: will not work for EVMS
y2milestone("calling addLogicalVolume with lv = %1 and current_vg = %2",lv, current_vg);
} else if( vmType == `CT_EVMS ) {
y2milestone("Storage::CreateEvmsVolume %1/%2",lvm_string,vgname);
y2milestone("lv = %1",lv);
Storage::CreateEvmsVolume(lvm_string+"/"+vgname,lv["name"]:"",lv["size_k"]:0,lv["stripes"]:1);
Storage::ChangeVolumeProperties(lv);
if( lv["stripesize"]:0 > 0 )
Storage::ChangeEvmsStripeSize( lvm_string+"/"+vgname, lv["name"]:"",
lv["stripesize"]:0 );
}
targetMap = Storage::GetTargetMap();
y2milestone("Storage::GetTargetMap returns %1",targetMap);
}
});
});
y2milestone("targetmap: %1" , targetMap );
return true;
}
}