ACC SHELL
/**
* Module: Storage.ycp
*
* Authors: Johannes Buchhold (jbuch@suse.de)
*
* Purpose: These module contains all settings/information which
* are needed to partitioning the harddisk. Futhermore it contains a interface
* to * access and modify the partitioning settings.
*
* Todo: Translate
* Diese Modul enthält alle Informationen die für die Partitionierung der
* Festplatten erforderlich sind. Diese Informationen bestehen aus der
* Beschreibung, der vor der Partitionierung vorhandenen Platteneinstellungen,
* und der Art und Weise wie diese verändert werden soll.
* Alle nötigen Zugriffsfunktionen auf diese Datenstruktur sind ebenfalls in
* diesem Modul enthalten. Der Zugriff auf die Speicherung der
* Partitionseinstellungen läuft also nur über dieses Modul.
* Der Zugriff und die Rückgabe von Teilen der Partitionsdatenstruktur
* wurde versucht "intelligent" zu gestallten und ist im einzelen bei den
* entspechenden Funktionen näher erklärt.
*
* $Id: Storage.ycp 62005 2010-05-12 14:57:07Z aschnell $
*/
{
module "Storage";
textdomain "storage";
import "Arch";
import "Directory";
import "FileSystems";
import "FileUtils";
import "Installation";
import "Label";
import "Icon";
import "Mode";
import "Partitions";
import "Popup";
import "Report";
import "Misc";
import "HTML";
import "StorageDevices";
import "StorageClients";
import "Stage";
import "String";
import "Hotplug";
import "LibStorage";
import "LibStorage::StorageInterface";
import "LibStorage::VolumeInfo";
import "LibStorage::PartitionInfo";
import "LibStorage::LvmLvInfo";
import "LibStorage::MdInfo";
import "LibStorage::LoopInfo";
import "LibStorage::DmInfo";
import "LibStorage::DmPartInfo";
import "LibStorage::DmraidInfo";
import "LibStorage::DmmultipathInfo";
import "LibStorage::MdPartCoInfo";
import "LibStorage::MdPartInfo";
import "LibStorage::NfsInfo";
import "LibStorage::ContainerInfo";
import "LibStorage::DiskInfo";
import "LibStorage::LvmVgInfo";
import "LibStorage::PartitionAddInfo";
import "LibStorage::DmPartCoInfo";
import "LibStorage::DmraidCoInfo";
import "LibStorage::DmmultipathCoInfo";
import "LibStorage::PartitionSlotInfo";
import "LibStorage::CommitInfo";
import "LibStorage::DlabelCapabilities";
import "LibStorage::ContVolInfo";
import "LibStorage::ResizeInfo";
import "LibStorage::ContentInfo";
import "LibStorage::Environment";
// simple resize functionality - dialog to set size of Linux and Windows before proposal
global string resize_partition = nil;
global map resize_partition_data = nil;
global integer resize_cyl_size = nil;
// end of resizing functions
map<string,any> conv_ctype =
$[ "def_sym" : `CT_UNKNOWN,
"def_int" : LibStorage::CUNKNOWN(),
"m" : $[ LibStorage::DISK() : `CT_DISK,
LibStorage::MD() : `CT_MD,
LibStorage::LOOP() : `CT_LOOP,
LibStorage::LVM() : `CT_LVM,
LibStorage::DMRAID() : `CT_DMRAID,
LibStorage::DMMULTIPATH() : `CT_DMMULTIPATH,
LibStorage::DM() : `CT_DM,
LibStorage::MDPART() : `CT_MDPART,
LibStorage::NFSC() : `CT_NFS
]
];
map<string,any> conv_usedby =
$[ "def_sym" : `UB_NONE,
"def_int" : LibStorage::UB_NONE(),
"m" : $[ LibStorage::UB_LVM() : `UB_LVM,
LibStorage::UB_MD() : `UB_MD,
LibStorage::UB_DMRAID() : `UB_DMRAID,
LibStorage::UB_DMMULTIPATH() : `UB_DMMULTIPATH,
LibStorage::UB_MDPART() : `UB_MDPART,
LibStorage::UB_DM() : `UB_DM
]
];
map<string,any> conv_ptype =
$[ "def_sym" : `primary,
"def_int" : LibStorage::PRIMARY(),
"m" : $[ LibStorage::LOGICAL() : `logical,
LibStorage::EXTENDED() : `extended
]
];
map<string,any> conv_mountby =
$[ "def_sym" : `device,
"def_int" : LibStorage::MOUNTBY_DEVICE(),
"m" : $[ LibStorage::MOUNTBY_UUID() : `uuid,
LibStorage::MOUNTBY_LABEL() : `label,
LibStorage::MOUNTBY_ID() : `id,
LibStorage::MOUNTBY_PATH() : `path
]
];
map<string,any> conv_encryption =
$[ "def_sym" : `none,
"def_int" : LibStorage::ENC_NONE(),
"m" : $[ LibStorage::ENC_TWOFISH() : `twofish,
LibStorage::ENC_TWOFISH_OLD() : `twofish_old,
LibStorage::ENC_TWOFISH256_OLD() : `twofish_256_old,
LibStorage::ENC_LUKS() : `luks,
LibStorage::ENC_UNKNOWN() : `unknown,
]
];
map<string,any> conv_mdtype =
$[ "def_sym" : `raid_unknown,
"def_int" : LibStorage::RAID_UNK(),
"m" : $[ LibStorage::RAID0() : `raid0,
LibStorage::RAID1() : `raid1,
LibStorage::RAID5() : `raid5,
LibStorage::RAID6() : `raid6,
LibStorage::RAID10() : `raid10,
LibStorage::MULTIPATH() : `multipath
]
];
map<string,integer> conv_mdstring =
$[ "raid0" : LibStorage::RAID0(),
"raid1" : LibStorage::RAID1(),
"raid5" : LibStorage::RAID5(),
"raid6" : LibStorage::RAID6(),
"raid10" : LibStorage::RAID10(),
"multipath" : LibStorage::MULTIPATH() ];
map<string,any> conv_mdparity =
$[ "def_sym" : `par_none,
"def_int" : LibStorage::PAR_NONE(),
"m" : $[ LibStorage::LEFT_ASYMMETRIC() : `left_asymmetric,
LibStorage::LEFT_SYMMETRIC() : `left_symmetric,
LibStorage::RIGHT_ASYMMETRIC() : `right_asymmetric,
LibStorage::RIGHT_SYMMETRIC() : `right_symmetric
]
];
map<string,integer> conv_parstring =
$[ "left_asymmetric" : LibStorage::LEFT_ASYMMETRIC(),
"left_symmetric" : LibStorage::LEFT_SYMMETRIC(),
"right_asymmetric" : LibStorage::RIGHT_ASYMMETRIC(),
"right_symmetric" : LibStorage::RIGHT_SYMMETRIC() ];
map<string,any> conv_partalign =
$[ "def_sym" : `align_optimal,
"def_int" : LibStorage::ALIGN_OPTIMAL(),
"m" : $[ LibStorage::ALIGN_OPTIMAL() : `align_optimal,
LibStorage::ALIGN_CYLINDER() : `align_cylinder
]
];
map DiskMapVersion = $[];
map DiskMap = $[];
const map<symbol, integer> type_order = $[ `CT_DISK : 0, `CT_MD : 1, `CT_MDPART : 2,
`CT_DMRAID : 3, `CT_DMMULTIPATH : 4, `CT_LOOP : 5, `CT_DM : 6, `CT_LVM : 7,
`CT_NFS : 8 ];
list<string> hw_packages = [];
string part_insts = nil;
global map<string, map> ReReadTargetMap();
global boolean IsKernelDeviceName(string device)
{
return substring(device, 0, 6) != "LABEL=" &&
substring(device, 0, 5) != "UUID=" &&
substring(device, 0, 13) != "/dev/disk/by-";
}
/* Storage = TargetMap
/* Storage = $[ "targets" : $[],
"must_reread_partitions" : false,
"win_device" : false,
"testsuite" : false,
"do_resize" : "",
"part_proposal_mode" : "",
"part_proposal_first" : true,
"focus" : key
]
*/
map StorageMap = $[];
/* stringkeys for access to the Storage map */
string targets_key = "targets";
string part_mode_key = "part_mode";
string part_disk_key = "part_disk";
string testsuite_key = "testsuite";
string do_resize_key = "do_resize";
string win_device_key = "win_device";
string custom_display_key = "custom_display";
string part_proposal_mode_key = "part_proposal_mode";
string part_proposal_first_key = "part_proposal_first";
string part_proposal_active_key = "part_proposal_active";
boolean probe_done = false;
symbol exit_key = `next;
any sint = nil;
list<map> conts = [];
string GetProcessName(integer pid)
{
string name = (string) SCR::Read(.target.symlink, "/proc/" + tostring(pid) + "/exe");
if (name == nil)
return nil;
integer pos = findlastof(name, "/");
if (pos == nil)
return name;
return substring(name, pos + 1);
}
any CreateInterface(boolean readonly)
{
while (sint == nil)
{
any env = LibStorage::Environment::new("LibStorage::Environment", readonly);
LibStorage::Environment::swig_testmode_set(env, Mode::test());
LibStorage::Environment::swig_autodetect_set(env, !Mode::test());
LibStorage::Environment::swig_instsys_set(env, Mode::installation() || Mode::repair());
integer locker_pid = 0;
sint = LibStorage::createStorageInterfacePid(env, locker_pid);
if (sint == nil)
{
string locker_name = GetProcessName(locker_pid);
y2milestone("locker_pid:%1 locker_name:%2", locker_pid, locker_name);
if (locker_name == nil)
{
if (!Popup::AnyQuestion(Label::ErrorMsg(),
// error popup
_("The storage subsystem is locked by an unknown application.
You must quit that application before you can continue."), Label::ContinueButton(),
Label::CancelButton(), `focus_no))
break;
}
else
{
if (!Popup::AnyQuestion(Label::ErrorMsg(),
// error popup
sformat(_("The storage subsystem is locked by the application \"%1\" (%2).
You must quit that application before you can continue."), locker_name, locker_pid),
Label::ContinueButton(), Label::CancelButton(),
`focus_no))
break;
}
}
}
y2milestone("sint:%1", sint);
return sint;
}
list<map> getContainers();
global boolean InitLibstorage(boolean readonly)
{
if (sint != nil)
return true;
y2milestone("InitLibstorage");
sint = CreateInterface(readonly);
if (sint == nil)
{
y2error("Storage::CreateInterface failed");
return false;
}
StorageClients::InstallCallbacks(sint);
if (Stage::initial())
{
LibStorage::StorageInterface::setDetectMountedVolumes(sint, false);
LibStorage::StorageInterface::setRootPrefix(sint, Installation::destdir);
}
LibStorage::StorageInterface::setEfiBoot(sint, Partitions::EfiBoot());
conts = getContainers();
y2milestone("InitLibstorage conts:%1", conts);
FileSystems::InitSlib(sint);
Partitions::InitSlib(sint);
return true;
}
global void FinishLibstorage()
{
if (sint == nil)
return;
y2milestone("FinishLibstorage");
LibStorage::destroyStorageInterface(sint);
sint = nil;
}
global integer ClassicStringToByte(string str)
{
integer bytes = 0;
if (!LibStorage::humanStringToByte(str, true, bytes))
y2error("cannot parse %1", str);
return bytes;
}
global string ByteToHumanString(integer bytes)
{
return LibStorage::byteToHumanString(bytes, false, 2, false);
}
global string KByteToHumanString(integer bytes_k)
{
return LibStorage::byteToHumanString(bytes_k * 1024, false, 2, false);
}
global string ByteToHumanStringOmitZeroes(integer bytes)
{
return LibStorage::byteToHumanString(bytes, false, 2, true);
}
global string KByteToHumanStringOmitZeroes(integer bytes_k)
{
return LibStorage::byteToHumanString(bytes_k * 1024, false, 2, true);
}
global boolean HumanStringToByte(string str, integer& bytes)
{
integer i = 0; bytes = i; // bnc #408829 and #408891
boolean ret = LibStorage::humanStringToByte(str, false, bytes);
y2milestone("HumanStringToByte ret:%1 str:%2 bytes:%3", ret, str, bytes);
return ret;
}
global boolean HumanStringToKByte(string str, integer& bytes_k)
{
integer bytes = 0; // bnc #408829
boolean ret = LibStorage::humanStringToByte(str, false, bytes);
bytes_k = bytes / 1024;
y2milestone("HumanStringToKByte ret:%1 str:%2 bytes_k:%3", ret, str, bytes_k);
return ret;
}
/**
* Converts a string into a integer and checks the allowed range for the
* integer. The range check is a bit sloppy to compensate rounding issues but
* it's guaranteed that the result lies within the allowed range.
*/
global boolean HumanStringToKByteWithRangeCheck(string str, integer& bytes_k, integer min_k,
integer max_k)
{
if (!HumanStringToKByte(str, bytes_k))
return false;
if (min_k != nil && bytes_k < min_k)
{
if (KByteToHumanString(bytes_k) != KByteToHumanString(min_k))
return false;
bytes_k = min_k;
}
if (max_k != nil && bytes_k > max_k)
{
if (KByteToHumanString(bytes_k) != KByteToHumanString(max_k))
return false;
bytes_k = max_k;
}
return true;
}
/**
* Returns Device Name
*
* @param string Disk
* @param any partition
* @return string device name
*
* @example Storage::GetDeviceName("/dev/md", 1)
* @example Storage::GetDeviceName("/dev/system", "root")
*/
global string GetDeviceName(string disk, any partition)
{
string ret = disk;
if (is(partition, integer))
{
ret = LibStorage::StorageInterface::getPartitionName(sint, disk, (integer) partition);
}
else if (size((string) partition ) > 0)
{
ret = ret + "/" + (string) partition;
}
return ret;
}
global boolean SetIgnoreFstab(string device, boolean val)
{
return LibStorage::StorageInterface::setIgnoreFstab(sint, device, val) == 0;
}
global boolean GetIgnoreFstab(string device, boolean& val)
{
return LibStorage::StorageInterface::getIgnoreFstab(sint, device, val) == 0;
}
global define map<string,map> GetTargetMap();
define list<map> GetDiskPartitionTg( string device, map<string,map> tg )
``{
list<map> ret = [];
integer dlen = 0;
boolean as_string = false;
list<string> ls = filter( string s, splitstring( device, "/" ),
``(size(s)>0));
if( search( device, "LABEL=" )==0 ||
search( device, "UUID=" )==0 )
{
list<string> tl = splitstring( device, "=" );
ls = [ "dev", "disk", "", tl[1]:"" ];
ls[2] = (search( device, "LABEL=" )==0)?"by-label":"by-uuid";
y2milestone( "GetDiskPartitionTg ls:%1", ls );
}
y2debug( "GetDiskPartitionTg size:%1 ls:%2", size(ls), ls );
if( size(ls)>=4 && ls[1]:"" == "disk" &&
contains( [ "by-id", "by-path", "by-uuid", "by-label" ], ls[2]:"" ))
{
map part = $[];
string regex = "-part[0-9]+$";
if( ls[2]:"" == "by-label" )
{
foreach( string dev, map disk, tg,
``{
part = find( map p, disk["partitions"]:[],
``(p["label"]:""==ls[3]:""));
if( part!=nil )
{
map tmp = $[];
tmp["disk"] = dev;
if( haskey( part, "nr" ))
tmp["nr"] = part["nr"]:(any)0;
else
tmp["nr"] = part["name"]:"";
ret = add( ret, tmp );
}
});
}
else if( ls[2]:"" == "by-uuid" )
{
foreach( string dev, map disk, tg,
``{
part = find( map p, disk["partitions"]:[],
``(p["uuid"]:""==ls[3]:""));
if( part!=nil )
{
map tmp = $[];
tmp["disk"] = dev;
if( haskey( part, "nr" ))
tmp["nr"] = part["nr"]:(any)0;
else
tmp["nr"] = part["name"]:"";
ret = add( ret, tmp );
}
});
}
else if( ls[2]:"" == "by-id" )
{
string id = ls[3]:"";
integer num = 0;
list l = regexppos( id, regex );
if( size(l)>0 )
{
num = tointeger( substring( id, l[0]:0+5 ));
id = substring( id, 0, l[0]:0 );
y2debug( "GetDiskPartitionTg id:%1 num:%2", id, num );
}
foreach( string dev, map disk, tg,
``{
if( size(ret)==0 &&
find( string s, disk["udev_id"]:[], ``(s==id))!=nil)
{
part = find( map p, disk["partitions"]:[],
``(p["nr"]:0==num));
if( num==0 || part!=nil )
{
map tmp = $[];
tmp["disk"] = dev;
if( num>0 )
tmp["nr"] = num;
else
tmp["nr"] = "";
ret = [ tmp ];
}
}
});
}
else if( ls[2]:"" == "by-path" )
{
string id = ls[3]:"";
integer num = 0;
list l = regexppos( id, regex );
if( size(l)>0 )
{
num = tointeger( substring( id, l[0]:0+5 ));
id = substring( id, 0, l[0]:0 );
y2debug( "GetDiskPartitionTg id:%1 num:%2", id, num );
}
foreach( string dev, map disk, tg,
``{
if( size(ret)==0 && disk["udev_path"]:"" == id )
{
part = find( map p, disk["partitions"]:[],
``(p["nr"]:0==num));
if( num==0 || part!=nil )
{
map tmp = $[];
tmp["disk"] = dev;
if( num>0 )
tmp["nr"] = num;
else
tmp["nr"] = "";
ret = [ tmp ];
}
}
});
}
}
else if( search( device, "/" )==0 )
{
if( search( device, "/dev/hd" )==0 ||
search( device, "/dev/sd" )==0 ||
search( device, "/dev/ed" )==0 ||
search( device, "/dev/iseries/vd" )==0 )
{
dlen = findfirstof( device, "0123456789" );
if( dlen == nil )
{
dlen = size(device);
}
}
else if( search( device, "/dev/md" )==0 && size(ls)==2 )
{
integer pos = search(device, "p");
if (pos != nil)
dlen = pos;
else
dlen = 7;
}
else if( search( device, "/dev/loop" )==0 )
{
dlen = 9;
}
else if( search( device, "/dev/i2o/hd" )==0 )
{
dlen = 12;
}
else if(LibStorage::StorageInterface::getPartitionPrefix(sint, device) == "p")
{
integer pos = findlastof( device, "p" );
dlen = size(device);
if( pos!=nil )
{
dlen = pos;
}
}
else if( search( device, "/dev/dasd" )==0 )
{
dlen = size(device);
if( findfirstof( device, "0123456789" )!=nil )
{
dlen = dlen-1;
}
}
else if( search( device, "/dev/mapper/" )==0 )
{
string regex = "[_-]part[0-9]+$";
list l = regexppos( device, regex );
if( size(l)>0 )
dlen = l[0]:0;
else
dlen = size(device);
}
else
{
as_string = true;
if( size(ls)>=3 )
{
integer pos = findlastof( device, "/" );
if( pos!=nil )
{
dlen = pos;
}
}
else
{
dlen = size(device);
integer nonzero = findlastnotof( device, "0123456789" );
if( nonzero!=nil && nonzero < dlen-1 )
{
dlen = nonzero+1;
as_string = false;
}
}
}
map tmp =$[];
tmp["disk"] = substring( device, 0, dlen );
device = substring( device, dlen );
if( search( device, "_part" )==0 )
device = substring( device, 5 );
if( size(device)>0 && findfirstof( device, "/p" )==0 )
{
device = substring( device, 1 );
}
tmp["nr"] = -1;
if( as_string )
{
tmp["nr"] = device;
}
else
{
if( size(device)>0 )
{
tmp["nr"] = tointeger(device);
}
}
if( size(tmp["disk"]:"")>0 && tmp["nr"]:(any)1 == -1 )
{
tmp["nr"] = "";
}
ret = [ tmp ];
}
else
{
ret = [ $[ "disk" : "/dev/nfs", "nr" : device ]];
}
y2debug( "GetDiskPartitionTg device:%1 ret:%2", device, ret );
return( ret );
};
/**
* Returns map describing the disk partition
*
* @param string device
* @return map DiskPartition
*
* Examples:
* "/dev/sda" -> $[ "disk" : "/dev/sda", "nr" : "" ]
* "/dev/sda2" -> $[ "disk" : "/dev/sda", "nr" : 2 ]
* "/dev/system" -> $[ "disk" : "/dev/system", "nr" : "" ]
* "/dev/system/abuild" -> $[ "disk" : "/dev/system", "nr" : "abuild" ]
*/
global define map GetDiskPartition( string device )
``{
return( GetDiskPartitionTg( device, GetTargetMap() )[0]:$[] );
};
global void UpdateChangeTime()
{
integer change_time = time();
y2milestone( "UpdateChangeTime time %1", change_time );
StorageMap["targets_time"] = change_time;
}
/* return list of partitions of map <tg> */
define list<map> GetPartitionLst( map<string,map> tg, string device )
``{
list<map> ret = [];
list<map> tmp = GetDiskPartitionTg( device, tg );
y2milestone( "GetPartitionLst tmp:%1", tmp );
foreach( map m, tmp,
``{
string disk = m["disk"]:"";
if( search(device, "/dev/evms")==0 && !haskey( tg, disk ) )
{
disk = "/dev/evms";
}
y2debug( "GetPartitionLst device=%1 disk=%2", device, disk );
list<map> part = filter( map p, tg[disk,"partitions"]:[],
``(p["device"]:""==device ));
part = filter( map p, part, ``(!p["delete"]:false));
if( size(part)==0 )
{
part = filter( map p, tg[disk,"partitions"]:[],
``(p["nr"]:-1==m["nr"]:0 ));
part = filter( map p, part, ``(!p["delete"]:false));
}
if( size(part)==0 )
{
part = filter( map p, tg[disk,"partitions"]:[],
``(p["name"]:""==m["nr"]:"" ));
part = filter( map p, part, ``(!p["delete"]:false));
}
map pa = part[0]:$[];
if( size(pa)==0 && search(device, "/dev/mapper/")==0 )
{
part = filter( map p, tg["/dev/mapper","partitions"]:[],
``(p["device"]:""==device ));
pa = part[0]:$[];
}
if( size(pa)==0 && search(device, "/dev/mapper/")==0 )
{
part = filter( map p, tg["/dev/loop","partitions"]:[],
``(p["device"]:""==device ));
pa = part[0]:$[];
}
if( size(pa)>0 )
ret = add( ret, pa );
});
y2debug( "GetPartitionLst ret=%1", ret );
return( ret );
}
global define map<string,any> GetPartition( map<string,map> tg, string device )
{
return( (map<string,any>)GetPartitionLst( tg, device )[0]:$[] );
}
/**
* Returns disk identified by 'device' taken from the 'tg' (target) map
*
* @param map<string,map> tg (target map)
* @param string device
*/
global define map<string,any> GetDisk( map<string,map> tg, string device )
``{
map<string,any> ret = $[];
map tmp = GetDiskPartitionTg( device, tg )[0]:$[];
string disk = tmp["disk"]:"";
if( search(device, "/dev/evms")==0 && !haskey( tg, disk ) )
{
disk = "/dev/evms";
}
y2debug( "GetDisk disk=%1", disk );
return( (map<string,any>)tg[disk]:$[] );
}
/**
* Get List of swap partitions
* @return list List of swap partitions
*/
global list<string> SwappingPartitions()
{
SCR::UnmountAgent(.proc.swaps);
list<map> swaps = (list<map>) SCR::Read(.proc.swaps);
if (swaps == nil) {
y2error("SCR::Read(.proc.swaps) returned nil");
y2milestone("/proc/swaps is %1", SCR::Execute(.target.bash_output, "cat /proc/swaps"));
swaps = [];
}
swaps = filter(map e, swaps, ``(e["type"]:""=="partition"));
list<string> ret = maplist(map e, swaps, ``(Partitions::TranslateMapperName(e["file"]:"")));
y2milestone("SwappingPartitions %1", ret);
return ret;
}
global boolean GetFreeInfo(string device, boolean get_resize, map<symbol, any>& resize_info,
boolean get_content, map<symbol, any>& content_info, boolean use_cache)
{
resize_info = $[];
content_info = $[];
any tmp1 = LibStorage::ResizeInfo::new("LibStorage::ResizeInfo");
any tmp2 = LibStorage::ContentInfo::new("LibStorage::ContentInfo");
boolean ret = LibStorage::StorageInterface::getFreeInfo(sint, device, get_resize, tmp1,
get_content, tmp2, use_cache);
if (ret)
{
if (get_resize)
{
resize_info = $[
`df_free_k : LibStorage::ResizeInfo::swig_df_freeK_get(tmp1),
`resize_free_k : LibStorage::ResizeInfo::swig_resize_freeK_get(tmp1),
`used_k : LibStorage::ResizeInfo::swig_usedK_get(tmp1),
`resize_ok : LibStorage::ResizeInfo::swig_resize_ok_get(tmp1)
];
}
if (get_content)
{
content_info = $[
`windows : LibStorage::ContentInfo::swig_windows_get(tmp2),
`efi : LibStorage::ContentInfo::swig_efi_get(tmp2),
`homes : LibStorage::ContentInfo::swig_homes_get(tmp2)
];
}
}
y2milestone("GetFreeInfo device:%1 ret:%2", device, ret);
return ret;
}
/**
* Returns map of free space per partition
*
* @param string device
* @param integer testsize
* @param symbol used_fs
* @param boolean verbose
*/
global map GetFreeSpace(string device, symbol used_fs, boolean verbose)
{
map<symbol, any> resize_info = $[];
map<symbol, any> content_info = $[];
boolean r = GetFreeInfo(device, true, resize_info, true, content_info, used_fs == `ntfs);
integer used = 1024 * resize_info[`used_k]:0;
integer resize_free = 1024 * resize_info[`resize_free_k]:0;
integer df_free = 1024 * resize_info[`df_free_k]:0;
boolean resize_ok = resize_info[`resize_ok]:false;
boolean win_disk = content_info[`windows]:false;
boolean efi = content_info[`efi]:false;
if( used_fs == `ntfs && (!r || !resize_ok) && verbose )
{
string cmd = sformat("/usr/sbin/ntfsresize -f -i '%1'", device);
y2milestone( "GetFreeSpace Executing cmd:%1", cmd );
map bcall = (map) SCR::Execute( .target.bash_output, cmd,
$[ "LC_MESSAGES" :"POSIX"] );
y2milestone( "GetFreeSpace Executing ret:%1", bcall );
string tmp = _("Resize Not Possible:") + "\n\n";
tmp = tmp + bcall["stdout"]:"" + bcall["stderr"]:"";
Popup::Error( tmp );
return( $[] );
}
integer linux_size = 0;
integer min_linux_size = 0;
integer add_free = df_free - resize_free;
y2milestone( "GetFreeSpace resize_free %1 add_free %2",
resize_free, add_free );
if( resize_free < 300*1024*1024 || !r )
{
linux_size = 0;
min_linux_size = 0;
}
else if( resize_free < 600*1024*1024 )
{
linux_size = resize_free;
if( add_free < 75*1024*1024 )
{
linux_size = linux_size - 75*1024*1024 + add_free;
}
min_linux_size = linux_size;
}
else if ( resize_free < 1024*1024*1024 )
{
linux_size = resize_free;
if( add_free < 200*1024*1024 )
{
linux_size = linux_size - 200*1024*1024 + add_free;
}
min_linux_size = 300*1024*1024;
}
else if ( resize_free < 2*1024*1024*1024 )
{
linux_size = resize_free;
if( add_free < 300*1024*1024 )
{
linux_size = linux_size - 300*1024*1024 + add_free;
}
min_linux_size = 500*1024*1024;
}
else if ( resize_free < 3*1024*1024*1024 )
{
linux_size = resize_free;
if( add_free < 800*1024*1024 )
{
linux_size = linux_size - 800*1024*1024 + add_free;
}
min_linux_size = 500*1024*1024;
}
else
{
linux_size = resize_free;
if( add_free < resize_free/3 )
{
linux_size = linux_size - resize_free/3 + add_free;
}
min_linux_size = 500*1024*1024;
}
integer new_size = used + add_free + resize_free - linux_size;
map ret = $[ "free": (resize_free>0?resize_free:0),
"df_free" : df_free,
"used":used,
"win_disk":win_disk,
"efi":efi,
"linux_size":linux_size,
"max_win_size":used + resize_free + add_free - min_linux_size,
"ntfs" : (used_fs == `ntfs),
"new_size":new_size ];
ret["ok"] = r;
y2milestone( "GetFreeSpace %1 ret %2", device, ret );
return ret;
}
global integer GetUnusedPartitionSlots(string device, list<map> &slots)
{
list<any> swig_slots = [];
integer ret = LibStorage::StorageInterface::getUnusedPartitionSlots(sint, device, swig_slots);
slots = maplist(any swig_slot, swig_slots, {
return $[
"region" : [ LibStorage::PartitionSlotInfo::swig_cylStart_get(swig_slot),
LibStorage::PartitionSlotInfo::swig_cylSize_get(swig_slot) ],
"primary_slot" : LibStorage::PartitionSlotInfo::swig_primarySlot_get(swig_slot),
"primary_possible" : LibStorage::PartitionSlotInfo::swig_primaryPossible_get(swig_slot),
"extended_slot" : LibStorage::PartitionSlotInfo::swig_extendedSlot_get(swig_slot),
"extended_possible" : LibStorage::PartitionSlotInfo::swig_extendedPossible_get(swig_slot),
"logical_Slot" : LibStorage::PartitionSlotInfo::swig_logicalSlot_get(swig_slot),
"logical_possible" : LibStorage::PartitionSlotInfo::swig_logicalPossible_get(swig_slot)
];
});
return ret;
}
global string SaveDumpPath(string name)
{
string ret = Directory::tmpdir + "/" + name;
return ret;
}
string convertFsOptionMapToString( map<any, map> fsopt, symbol cmd )
{
string ret = "";
// do nothing
if( fsopt != nil || fsopt != $[] )
{
list ignore = [ "auto", "default", "none", "" ];
foreach(any option_key, map option, fsopt,
``{
string option_str = option["option_str"]:"";
any option_value = option["option_value"]:(any)"";
boolean option_blank = option["option_blank"]:false;
symbol option_cmd = option["option_cmd"]:`mkfs;
y2milestone( "convertFsOptionMapToString k:%1 opt:%2 val:%3 cmd:%4",
option_key, option, option_value, option_cmd );
if (cmd == option_cmd)
{
if( is(option_value, string) && option_value != nil )
{
if( !contains( ignore, option_value ))
{
if( size(ret)>0 )
ret = ret + " ";
ret = ret + option_str;
if( option_blank )
ret = ret + " ";
ret = ret + (string)option_value;
}
}
else if( is(option_value, boolean) && option_value != nil )
{
if( (boolean) option_value )
{
if( size(ret)>0 )
ret = ret + " ";
ret = ret + option_str;
}
}
else if( is(option_value, integer) && option_value != nil )
{
if( size(ret)>0 )
ret = ret + " ";
ret = ret + option_str;
if( option_blank )
ret = ret + " ";
ret = ret + sformat("%1", option_value);
}
}
});
}
if( size(fsopt)>0 || size(ret)>0 )
y2milestone( "convertFsOptionMapToString fsopt:%1 ret:%2", fsopt, ret );
return ret;
};
map<any, map> convertStringToFsOptionMap( string opts, symbol fs, symbol cmd )
{
map<any, map> ret = $[];
y2milestone( "convertStringToFsOptionMap opts:\"%1\" fs:%2 cmd:%3", opts, fs, cmd );
integer pos = findfirstnotof( opts, " \t" );
if( pos>0 )
opts = substring( opts, pos );
list<map> op = (list<map>)FileSystems::GetOptions(fs);
op = filter(map o, op, { return o[`option_cmd]:`mkfs == cmd; });
while( size(opts)>0 )
{
boolean found = false;
foreach( map o, op,
``{
map m = $[];
string os = o[`option_str]:"";
if( !found && size(os)>0 && search( opts, os )==0 )
{
found = true;
m["option_str"] = os;
m["option_cmd"] = o[`option_cmd]:`mkfs;
if( o[`type]:`text==`boolean )
{
m["option_value"] = true;
ret[o[`query_key]:""] = m;
}
opts = substring( opts, size(os) );
pos = findfirstnotof( opts, " \t" );
if( pos>0 )
opts = substring( opts, pos );
if( o[`type]:`text!=`boolean && size(opts)>0 &&
search(opts,"-")!=0 )
{
if( pos>0 )
m["option_blank"] = true;
pos = findfirstof( opts, " \t" );
if( pos==nil )
{
m["option_value"] = opts;
opts = "";
}
else
{
m["option_value"] = substring( opts, 0, pos );
opts = substring( opts, pos );
}
ret[o[`query_key]:""] = m;
}
pos = findfirstnotof( opts, " \t" );
if( pos>0 )
opts = substring( opts, pos );
}
});
if( !found )
{
pos = findfirstnotof( opts, " \t" );
if( pos>0 )
opts = substring( opts, pos );
else
opts = "";
}
y2milestone( "convertStringToFsOptionMap opts:%1 ret:%2", opts, ret );
}
y2milestone( "convertStringToFsOptionMap ret:%1", ret );
return( ret );
}
symbol toSymbol( map<string,any> conv, integer val )
{
return( conv["m",val]:(conv["def_sym"]:`invalid_conv_map) );
}
integer fromSymbol( map<string,any> conv, symbol val )
{
integer ret = conv["def_int"]:-1;
foreach( integer i, symbol s, conv["m"]:$[],
``{
if( s==val )
ret = i;
});
return( ret );
}
global define boolean CheckBackupState( string who )
{
y2milestone( "CheckBackupStates who:%1", who );
if (!InitLibstorage(false))
return nil;
boolean ret = LibStorage::StorageInterface::checkBackupState( sint, who );
y2milestone( "CheckBackupStates ret:%1", ret );
return( ret );
}
map diskMap( any dinfo, map d )
{
d["size_k"] = LibStorage::DiskInfo::swig_sizeK_get(dinfo);
d["cyl_size"] = LibStorage::DiskInfo::swig_cylSize_get(dinfo);
d["cyl_count"] = LibStorage::DiskInfo::swig_cyl_get(dinfo);
d["sector_size"] = LibStorage::DiskInfo::swig_sectorSize_get(dinfo);
d["label"] = LibStorage::DiskInfo::swig_disklabel_get(dinfo);
d["max_logical"] = LibStorage::DiskInfo::swig_maxLogical_get(dinfo);
d["max_primary"] = LibStorage::DiskInfo::swig_maxPrimary_get(dinfo);
boolean bt = LibStorage::DiskInfo::swig_iscsi_get(dinfo);
if( bt )
d["iscsi"] = true;
else if( haskey( d, "iscsi" ))
d = remove( d, "iscsi" );
bt = LibStorage::DiskInfo::swig_initDisk_get(dinfo);
if( bt )
d["dasdfmt"] = true;
else if( haskey( d, "dasdfmt" ))
d = remove( d, "dasdfmt" );
y2milestone( "diskMap ret:%1", d );
return( d );
}
map dmPartCoMap( any infos, map d )
{
any dinfo = LibStorage::DmPartCoInfo::swig_d_get(infos);
d = diskMap( dinfo, d );
list<string> ls = splitstring( LibStorage::DmPartCoInfo::swig_devices_get(infos), " " );
y2milestone( "ls=%1", ls );
d["devices"] = ls;
integer t = LibStorage::DmPartCoInfo::swig_minor_get(infos);
d["minor"] = t;
y2milestone( "dmPartCoMap ret:%1", d );
return( d );
}
map volumeMap( any vinfo, map p )
{
p["device"] = LibStorage::VolumeInfo::swig_device_get(vinfo);
string tmp = LibStorage::VolumeInfo::swig_crypt_device_get(vinfo);
if( size(tmp)>0 )
p["crypt_device"] = tmp;
p["size_k"] = LibStorage::VolumeInfo::swig_sizeK_get(vinfo);
p["name"] = LibStorage::VolumeInfo::swig_name_get(vinfo);
integer t = LibStorage::VolumeInfo::swig_fs_get(vinfo);
symbol fs = toSymbol( FileSystems::conv_fs, t );
if( fs!=`unknown )
p["used_fs"] = fs;
t = LibStorage::VolumeInfo::swig_detected_fs_get(vinfo);
fs = toSymbol( FileSystems::conv_fs, t );
p["detected_fs"] = fs;
boolean tbool = LibStorage::VolumeInfo::swig_format_get(vinfo);
if( tbool )
p["format"] = true;
tbool = LibStorage::VolumeInfo::swig_create_get(vinfo);
if( tbool )
p["create"] = true;
tmp = LibStorage::VolumeInfo::swig_mount_get(vinfo);
if( size(tmp)>0 )
{
p["mount"] = tmp;
tbool = LibStorage::VolumeInfo::swig_is_mounted_get(vinfo);
if( !tbool )
p["inactive"] = true;
t = LibStorage::VolumeInfo::swig_mount_by_get(vinfo);
p["mountby"] = toSymbol( conv_mountby, t );
}
t = LibStorage::VolumeInfo::swig_usedByType_get(vinfo);
if( t!=LibStorage::UB_NONE() )
{
p["used_by_type"] = toSymbol( conv_usedby, t );
p["used_by_device"] = LibStorage::VolumeInfo::swig_usedByDevice_get(vinfo);
p["used_by"] = [ $[ "type" : p["used_by_type"]:`UB_NONE,
"device" : p["used_by_device"]:"" ] ];
}
tmp = LibStorage::VolumeInfo::swig_fstab_options_get(vinfo);
if( size(tmp)>0 )
{
p["fstopt"] = tmp;
if( find( string s, splitstring( tmp, "," ), ``(s=="noauto") )!=nil )
p["noauto"] = true;
}
tmp = LibStorage::VolumeInfo::swig_mkfs_options_get(vinfo);
if( size(tmp)>0 )
{
p["mkfs_opt"] = tmp;
p["fs_options"] =
convertStringToFsOptionMap( tmp, p["used_fs"]:`unknown, `mkfs );
}
else
{
if( haskey( p, "fs_options" ))
p = remove( p, "fs_options" );
}
tmp = LibStorage::VolumeInfo::swig_tunefs_options_get(vinfo);
if( size(tmp)>0 )
{
p["tunefs_opt"] = tmp;
p["fs_options"] = union(p["fs_options"]:$[],
convertStringToFsOptionMap( tmp, p["used_fs"]:`unknown, `tunefs ));
}
tmp = LibStorage::VolumeInfo::swig_dtxt_get(vinfo);
if( size(tmp)>0 )
p["dtxt"] = tmp;
tmp = LibStorage::VolumeInfo::swig_uuid_get(vinfo);
if( size(tmp)>0 )
p["uuid"] = tmp;
tmp = LibStorage::VolumeInfo::swig_label_get(vinfo);
if( size(tmp)>0 )
p["label"] = tmp;
t = LibStorage::VolumeInfo::swig_encryption_get(vinfo);
if( t!=LibStorage::ENC_NONE() )
{
p["enc_type"] = toSymbol( conv_encryption, t );
}
tbool = LibStorage::VolumeInfo::swig_resize_get(vinfo);
if( tbool )
{
p["resize"] = true;
p["orig_size_k"] = LibStorage::VolumeInfo::swig_origSizeK_get(vinfo);
}
tbool = LibStorage::VolumeInfo::swig_ignore_fs_get(vinfo);
if( tbool )
p["ignore_fs"] = true;
tmp = LibStorage::VolumeInfo::swig_loop_get(vinfo);
if( size(tmp)>0 )
p["loop"] = tmp;
tmp = LibStorage::VolumeInfo::swig_udevPath_get(vinfo);
if (!isempty(tmp))
p["udev_path"] = tmp;
tmp = LibStorage::VolumeInfo::swig_udevId_get(vinfo);
if (!isempty(tmp))
p["udev_id"] = splitstring(tmp, " ");
return( p );
}
map partAddMap( any info, map p )
{
p["nr"] = LibStorage::PartitionAddInfo::swig_nr_get(info);
p["fsid"] = LibStorage::PartitionAddInfo::swig_id_get(info);
p["fstype"] = Partitions::FsIdToString( p["fsid"]:0 );
p["region"] = [ LibStorage::PartitionAddInfo::swig_cylStart_get(info),
LibStorage::PartitionAddInfo::swig_cylSize_get(info) ];
integer t = LibStorage::PartitionAddInfo::swig_partitionType_get(info);
p["type"] = toSymbol( conv_ptype, t );
boolean boot = LibStorage::PartitionAddInfo::swig_boot_get(info);
if( boot )
p["boot"] = true;
y2milestone( "partAddMap ret:%1", p );
return( p );
}
map dmPartMap( any info, map p )
{
any vinfo = LibStorage::DmPartInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["nr"] = 0;
boolean part = LibStorage::DmPartInfo::swig_part_get(info);
if( part )
{
any pinfo = LibStorage::DmPartInfo::swig_p_get(info);
p = partAddMap( pinfo, p );
}
y2milestone( "dmPartMap ret:%1", p );
return( p );
}
map mdPartMap(any info, map p)
{
any vinfo = LibStorage::MdPartInfo::swig_v_get(info);
p = volumeMap(vinfo, p);
p["nr"] = 0;
boolean part = LibStorage::MdPartInfo::swig_part_get(info);
if (part)
{
any pinfo = LibStorage::MdPartInfo::swig_p_get(info);
p = partAddMap(pinfo, p);
}
y2milestone("mdPartMap ret:%1", p);
return p;
}
map getContainerInfo( map c )
{
y2milestone( "getContainerInfo %1", c );
integer ret = 0;
integer t = 0;
any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
if( c["type"]:`CT_UNKNOWN == `CT_DISK )
{
list<any> pinfos = [];
any infos = LibStorage::DiskInfo::new("LibStorage::DiskInfo");
string d = c["device"]:"";
ret = LibStorage::StorageInterface::getDiskInfo( sint, d, infos );
if( ret==0 )
{
c = diskMap( infos, c );
}
else
y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
c["partitions"] = [];
ret = LibStorage::StorageInterface::getPartitionInfo( sint, d, pinfos );
foreach( any info, pinfos,
``{
string tmp = "";
map p = $[];
vinfo = LibStorage::PartitionInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["nr"] = LibStorage::PartitionInfo::swig_nr_get(info);
p["fsid"] = LibStorage::PartitionInfo::swig_id_get(info);
p["fstype"] = Partitions::FsIdToString( p["fsid"]:0 );
p["region"] = [ LibStorage::PartitionInfo::swig_cylStart_get(info),
LibStorage::PartitionInfo::swig_cylSize_get(info) ];
t = LibStorage::PartitionInfo::swig_partitionType_get(info);
p["type"] = toSymbol( conv_ptype, t );
boolean boot = LibStorage::PartitionInfo::swig_boot_get(info);
if( boot )
p["boot"] = true;
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_DMRAID )
{
list<any> pinfos = [];
any infos = LibStorage::DmraidCoInfo::new("LibStorage::DmraidCoInfo");
string d = c["device"]:"";
ret = LibStorage::StorageInterface::getDmraidCoInfo( sint, d, infos );
if( ret==0 )
{
any pinfo = LibStorage::DmraidCoInfo::swig_p_get( infos );
c = dmPartCoMap( pinfo, c );
}
else
y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
c["partitions"] = [];
ret = LibStorage::StorageInterface::getDmraidInfo( sint, d, pinfos );
foreach( any info, pinfos,
``{
any pinfo = LibStorage::DmraidInfo::swig_p_get( info );
map p = $[];
p = dmPartMap( pinfo, p );
p["fstype"] = Partitions::dmraid_name;
if( p["nr"]:-1 != 0 )
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_DMMULTIPATH )
{
list<any> pinfos = [];
any infos = LibStorage::DmmultipathCoInfo::new("LibStorage::DmmultipathCoInfo");
string d = c["device"]:"";
ret = LibStorage::StorageInterface::getDmmultipathCoInfo( sint, d, infos );
if( ret==0 )
{
any pinfo = LibStorage::DmmultipathCoInfo::swig_p_get( infos );
c = dmPartCoMap( pinfo, c );
}
else
y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
c["partitions"] = [];
ret = LibStorage::StorageInterface::getDmmultipathInfo( sint, d, pinfos );
foreach( any info, pinfos,
``{
any pinfo = LibStorage::DmmultipathInfo::swig_p_get( info );
map p = $[];
p = dmPartMap( pinfo, p );
p["fstype"] = Partitions::dmmultipath_name;
if( p["nr"]:-1 != 0 )
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_MDPART )
{
list<any> pinfos = [];
any infos = LibStorage::MdPartCoInfo::new("LibStorage::MdPartCoInfo");
string d = c["device"]:"";
ret = LibStorage::StorageInterface::getMdPartCoInfo(sint, d, infos);
if (ret == 0)
{
any dinfo = LibStorage::MdPartCoInfo::swig_d_get(infos);
c = diskMap(dinfo, c);
}
else
y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
list<string> ls = splitstring(LibStorage::MdPartCoInfo::swig_devices_get(infos), " ");
y2milestone( "ls=%1", ls );
c["devices"] = ls;
integer t = LibStorage::MdPartCoInfo::swig_type_get(infos);
c["raid_type"] = substring(sformat("%1", toSymbol(conv_mdtype, t)), 1);
if (c["raid_type"]:"" == "raid5")
{
t = LibStorage::MdPartCoInfo::swig_parity_get(infos);
symbol pt = toSymbol(conv_mdparity, t);
if (pt != `par_none)
c["parity_algorithm"] = substring(sformat("%1", pt), 1);
}
t = LibStorage::MdPartCoInfo::swig_chunkSizeK_get(infos);
if (t > 0)
{
c["chunk_size"] = t;
}
c["sb_ver"] = LibStorage::MdPartCoInfo::swig_sb_ver_get(infos);
c["partitions"] = [];
ret = LibStorage::StorageInterface::getMdPartInfo(sint, d, pinfos);
foreach(any info, pinfos, {
map p = $[];
p = mdPartMap(info, p);
p["fstype"] = Partitions::raid_name;
if (p["nr"]:-1 != 0)
c["partitions"] = add(c["partitions"]:[], p);
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_LVM )
{
list<any> pinfos = [];
any infos = LibStorage::LvmVgInfo::new("LibStorage::LvmVgInfo");
string n = c["name"]:"";
ret = LibStorage::StorageInterface::getLvmVgInfo( sint, n, infos );
if( ret==0 )
{
c["create"] = LibStorage::LvmVgInfo::swig_create_get(infos);
c["size_k"] = LibStorage::LvmVgInfo::swig_sizeK_get(infos);
c["cyl_size"] = 1024*LibStorage::LvmVgInfo::swig_peSizeK_get(infos);
c["pesize"] = 1024*LibStorage::LvmVgInfo::swig_peSizeK_get(infos);
c["cyl_count"] = LibStorage::LvmVgInfo::swig_peCount_get(infos);
c["pe_free"] = LibStorage::LvmVgInfo::swig_peFree_get(infos);
c["lvm2"] = LibStorage::LvmVgInfo::swig_lvm2_get(infos);
list<string> ls = splitstring( LibStorage::LvmVgInfo::swig_devices_get(infos), " " );
y2milestone( "ls=%1", ls );
c["devices"] = ls;
ls = splitstring( LibStorage::LvmVgInfo::swig_devices_add_get(infos), " " );
if( size(ls)>0 )
c["devices_add"] = ls;
ls = splitstring( LibStorage::LvmVgInfo::swig_devices_rem_get(infos), " " );
if( size(ls)>0 )
c["devices_rem"] = ls;
}
else
y2warning( "LVM Vg \"%1\" ret:%2", c["name"]:"", ret );
ret = LibStorage::StorageInterface::getLvmLvInfo( sint, n, pinfos );
foreach( any info, pinfos,
``{
map p = $[];
vinfo = LibStorage::LvmLvInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["stripes"] = LibStorage::LvmLvInfo::swig_stripes_get(info);
t = LibStorage::LvmLvInfo::swig_stripeSizeK_get(info);
if( t>0 )
p["stripesize"] = t;
p["type"] = `lvm;
p["fstype"] = Partitions::lv_name;
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_MD )
{
list<any> pinfos = [];
ret = LibStorage::StorageInterface::getMdInfo( sint, pinfos );
if( ret<0 )
y2warning( "getMdInfo ret:%1", ret );
foreach( any info, pinfos,
``{
map p = $[];
vinfo = LibStorage::MdInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["nr"] = LibStorage::MdInfo::swig_nr_get(info);
integer t = LibStorage::MdInfo::swig_type_get(info);
p["raid_type"] = substring( sformat( "%1", toSymbol( conv_mdtype, t )), 1 );
if( p["raid_type"]:""=="raid5" )
{
t = LibStorage::MdInfo::swig_parity_get(info);
symbol pt = toSymbol( conv_mdparity, t );
if( pt != `par_none )
p["parity_algorithm"] = substring( sformat( "%1", pt), 1 );
}
p["type"] = `sw_raid;
p["fstype"] = Partitions::raid_name;
t = LibStorage::MdInfo::swig_chunkSizeK_get(info);
if( t>0 )
{
p["chunk_size"] = t;
}
string d = LibStorage::MdInfo::swig_sb_ver_get(info);
p["sb_ver"] = d;
list<string> ls = splitstring( LibStorage::MdInfo::swig_devices_get(info), " " );
p["devices"] = ls;
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_LOOP )
{
list<any> pinfos = [];
ret = LibStorage::StorageInterface::getLoopInfo( sint, pinfos );
if( ret<0 )
y2warning( "getLoopInfo ret:%1", ret );
foreach( any info, pinfos,
``{
map p = $[];
vinfo = LibStorage::LoopInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["nr"] = LibStorage::LoopInfo::swig_nr_get(info);
p["type"] = `loop;
p["fstype"] = Partitions::loop_name;
p["fpath"] = LibStorage::LoopInfo::swig_file_get(info);
p["create_file"] = !LibStorage::LoopInfo::swig_reuseFile_get(info);
if( p["enc_type"]:`unknown != `luks && size(p["loop"]:"")>0 )
p["device"] = p["loop"]:"";
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_DM )
{
list<any> pinfos = [];
ret = LibStorage::StorageInterface::getDmInfo( sint, pinfos );
if( ret<0 )
y2warning( "getDmInfo ret:%1", ret );
foreach( any info, pinfos,
``{
map p = $[];
vinfo = LibStorage::DmInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["nr"] = LibStorage::DmInfo::swig_nr_get(info);
p["type"] = `dm;
p["fstype"] = Partitions::dm_name;
c["partitions"] = add( c["partitions"]:[], p );
});
}
else if( c["type"]:`CT_UNKNOWN == `CT_NFS )
{
list<any> pinfos = [];
y2milestone( "before getNfsInfo" );
ret = LibStorage::StorageInterface::getNfsInfo( sint, pinfos );
y2milestone( "after getNfsInfo" );
if( ret<0 )
y2warning( "getNfsInfo ret:%1", ret );
foreach( any info, pinfos,
``{
map p = $[];
vinfo = LibStorage::NfsInfo::swig_v_get(info);
p = volumeMap( vinfo, p );
p["type"] = `nfs;
p["fstype"] = Partitions::nfs_name;
c["partitions"] = add( c["partitions"]:[], p );
});
}
//y2milestone ("getContainerInfo container %1", remove( c, "partitions" ) );
y2milestone ("getContainerInfo container %1", c );
return( c );
}
map toDiskMap( map disk, map cinfo )
{
list<string> l = [ "size_k", "cyl_size", "cyl_count", "sector_size", "label", "name", "device",
"max_logical", "max_primary", "type", "readonly",
"used_by", "used_by_type", "used_by_device", "partitions", "dasdfmt",
"udev_id", "udev_path" ];
foreach( string s, l,
``{
if( haskey( cinfo, s ) )
disk[s] = cinfo[s]:(any)0;
else if( haskey( disk, s ))
disk = remove( disk, s );
});
return( disk );
}
list<map> getContainers()
``{
list<map> ret = [];
list<any> cinfos = [];
LibStorage::StorageInterface::getContainers( sint, cinfos );
foreach( any info, cinfos,
``{
map c = $[];
c["name"] = LibStorage::ContainerInfo::swig_name_get(info);
c["device"] = LibStorage::ContainerInfo::swig_device_get(info);
integer t = LibStorage::ContainerInfo::swig_type_get(info);
c["type"] = toSymbol( conv_ctype, t );
t = LibStorage::ContainerInfo::swig_usedByType_get(info);
if( t!=LibStorage::UB_NONE() )
{
c["used_by_type"] = toSymbol( conv_usedby, t );
c["used_by_device"] = LibStorage::ContainerInfo::swig_usedByDevice_get(info);
c["used_by"] = [ $[ "type" : c["used_by_type"]:`UB_NONE,
"device" : c["used_by_device"]:"" ] ];
}
boolean b = LibStorage::ContainerInfo::swig_readonly_get(info);
if( b )
c["readonly"] = true;
string tmp = LibStorage::ContainerInfo::swig_udevPath_get(info);
if (!isempty(tmp))
c["udev_path"] = tmp;
tmp = LibStorage::ContainerInfo::swig_udevId_get(info);
if (!isempty(tmp))
c["udev_id"] = splitstring(tmp, " ");
ret = add( ret, c );
});
y2milestone( "getContainers ret:%1", ret );
return( ret );
};
integer count=0;
global boolean IsDiskType(symbol t)
{
return contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH, `CT_MDPART ], t);
}
/**
* Updates target map
*
* @see GetTargetMap()
*/
void UpdateTargetMap()
{
conts = getContainers();
list<string> rem_keys = [];
map<string,map> tg = StorageMap[targets_key]:$[];
//SCR::Write(.target.ycp, "/tmp/upd_all_bef_"+sformat("%1",count), StorageMap[targets_key]:$[] );
foreach( string dev, map disk, tg,
``{
map c = $[];
c = find( map c, conts, ``(c["device"]:""==dev) );
if( c==nil )
rem_keys = add( rem_keys, dev );
else if (IsDiskType(c["type"]:`CT_UNKNOWN))
{
tg[dev] = toDiskMap( tg[dev]:$[], getContainerInfo( c ) );
}
else
{
tg[dev] = getContainerInfo(c);
}
y2milestone( "UpdateTargetMap dev:%1 is:%2", dev, tg[dev]:$[] );
});
y2milestone( "UpdateTargetMap rem_keys:%1", rem_keys );
foreach( string dev, rem_keys, ``{tg=remove(tg,dev);});
foreach( map c, conts,
``{
if( c["type"]:`CT_UNKNOWN!=`CT_DISK && !haskey( tg, c["device"]:"" ))
{
tg[c["device"]:""] = getContainerInfo(c);
y2milestone( "UpdateTargetMap dev:%1 is:%2", c["device"]:"",
tg[c["device"]:""]:$[] );
}
});
StorageMap[targets_key] = tg;
//SCR::Write(.target.ycp, "/tmp/upd_all_aft_"+sformat("%1",count), StorageMap[targets_key]:$[] );
//count = count+1;
}
define void UpdateTargetMapDisk( string dev )
{
y2milestone( "UpdateTargetMapDisk" );
conts = getContainers();
map c = $[];
c = find( map c, conts, ``(c["device"]:""==dev) );
map tg = StorageMap[targets_key]:$[];
//SCR::Write(.target.ycp, "/tmp/upd_disk_bef_"+sformat("%1",count), StorageMap[targets_key]:$[] );
if( c==nil )
{
if( haskey( tg, dev ) )
tg = remove( tg, dev );
}
else if (IsDiskType(c["type"]:`CT_UNKNOWN))
{
tg[dev] = toDiskMap( tg[dev]:$[], getContainerInfo( c ) );
}
else
{
tg[dev] = getContainerInfo(c);
}
StorageMap[targets_key] = tg;
//SCR::Write(.target.ycp, "/tmp/upd_disk_aft_"+sformat("%1",count), StorageMap[targets_key]:$[] );
//count = count+1;
}
define void UpdateTargetMapDev( string dev )
{
y2milestone( "UpdateTargetMapDev %1", dev );
map<string,map> tg = StorageMap[targets_key]:$[];
//SCR::Write(.target.ycp, "/tmp/upd_dev_bef_"+sformat("%1",count), tg );
string cdev="";
foreach( string key, map d, tg,
``{
if( size(cdev)==0 &&
find( map p, d["partitions"]:[], ``(p["device"]:""==dev))!=nil )
cdev = d["device"]:"";
});
y2milestone( "UpdateTargetMapDev cdev %1", cdev );
map c = $[];
c = find( map c, conts, ``(c["device"]:""==cdev) );
map disk = $[];
if( c!=nil )
{
disk = getContainerInfo( c );
}
if( c!=nil && haskey( tg, cdev ))
{
list<map> partitions = tg[cdev,"partitions"]:[];
boolean found = false;
partitions = maplist( map p, partitions,
``{
if( p["device"]:"" == dev )
{
map pp = find( map q, disk["partitions"]:[],
``(q["device"]:""==dev));
if( pp!=nil )
{
found = true;
p = pp;
}
}
return( p );
});
tg[disk["device"]:"","partitions"] = partitions;
if( !found )
y2error( "UpdateTargetMapDev not found %1", dev );
}
else
y2error( "UpdateTargetMapDev key %1 not found in target", disk["device"]:"" );
StorageMap[targets_key] = tg;
//SCR::Write(.target.ycp, "/tmp/upd_dev_aft_"+sformat("%1",count), StorageMap[targets_key]:$[] );
//count = count+1;
}
/**
* Returns map with disk info
*
* @param string device
* @param map disk
* @return map disk info
*/
map getDiskInfo(string device, map disk)
{
map c = $[];
c = find( map p, conts, ``(p["device"]:""==device ));
if( c==nil )
{
map tmp = GetDiskPartition( device );
y2milestone( "getDiskInfo map %1", tmp );
if( tmp["disk"]:"" != device )
c = find( map p, conts, ``(p["device"]:""==tmp["disk"]:"" ));
}
y2milestone( "getDiskInfo c:%1", c );
if( c!=nil )
{
disk = toDiskMap( disk, getContainerInfo( c ) );
y2milestone( "getDiskInfo ret:%1",
haskey(disk,"partitions")?remove(disk,"partitions"):disk );
}
return( disk );
}
global define void SaveExitKey( symbol key )
``{
if( key == `next || key == `back )
{
exit_key = key;
y2milestone( "Exit Key %1", exit_key );
}
};
global define symbol GetExitKey()
``{
return( exit_key );
};
/**
* Returns map describing the disk target
*
* @return map <string, map>
*/
global map<string, map> GetOndiskTarget()
{
list<string> keys = [ "mount", "enc_type", "mountby", "fstopt", "used_fs", "format" ];
map<string,map> ret = GetTargetMap();
foreach( string d, map disk, ret,
``{
list<map> pl =
maplist( map<string,any> p, disk["partitions"]:[],
``( filter( string k, any e, p, ``(!contains(keys,k)))));
pl = maplist( map p, pl,
``({
if( p["detected_fs"]:`unknown!=`unknown )
p["used_fs"] = p["detected_fs"]:`unknown;
return(p);
}));
ret[d,"partitions"] = pl;
});
return ret;
}
global define void CreateTargetBackup(string who)
{
string t = "targetMap_s_" + who + "_" + sformat("%1",count);
count = count+1;
SCR::Write(.target.ycp, Storage::SaveDumpPath(t), GetTargetMap() );
y2milestone( "CreateTargetBackup who:%1", who );
integer ret = LibStorage::StorageInterface::createBackupState( sint, who );
if( ret<0 )
y2error( "CreateTargetBackup sint ret:%1", ret );
}
global define void DisposeTargetBackup(string who)
{
y2milestone( "DisposeTargetBackup who:%1", who );
integer ret = LibStorage::StorageInterface::removeBackupState( sint, who );
if( ret<0 )
y2error( "DisposeTargetBackup sint ret:%1", ret );
}
global define boolean EqualBackupStates( string s1, string s2, boolean vb )
{
y2milestone( "EqualBackupStates s1:\"%1\" s2:\"%2\" verbose:%3",
s1, s2, vb );
boolean ret = LibStorage::StorageInterface::equalBackupStates( sint, s1,
s2, vb );
y2milestone( "EqualBackupStates ret:%1", ret );
return( ret );
}
global define void RestoreTargetBackup( string who )
{
y2milestone( "RestoreTargetBackup who:%1", who );
integer ret = LibStorage::StorageInterface::restoreBackupState( sint, who );
if( ret<0 )
y2error( "RestoreTargetBackup sint ret:%1", ret );
UpdateTargetMap();
string t = "targetMap_r_" + who;
SCR::Write(.target.ycp, Storage::SaveDumpPath(t), GetTargetMap() );
}
global define void ResetOndiskTarget()
{
RestoreTargetBackup( "initial" );
}
global define integer GetTargetChangeTime()
{
return( StorageMap["targets_time"]:0 );
}
global define boolean GetPartProposalActive()
{
return StorageMap[part_proposal_active_key]:true;
};
global define void SetPartProposalActive( boolean value )
{
StorageMap[part_proposal_active_key] = value;
};
global define string GetPartMode()
{
y2milestone( "GetPartMode %1", StorageMap[part_mode_key]:"" );
return StorageMap[part_mode_key]:"";
};
global define void SetPartMode( string value )
{
y2milestone( "SetPartMode %1", value );
StorageMap[part_mode_key] = value;
};
global define boolean GetCustomDisplay()
{
return StorageMap[custom_display_key]:false;
};
global define void SetCustomDisplay( boolean value )
{
StorageMap[custom_display_key] = value;
};
global define string GetPartDisk()
{
return StorageMap[part_disk_key]:"";
};
global define void SetPartDisk( string value )
{
StorageMap[part_disk_key] = value;
};
global define boolean GetTestsuite()``{
return StorageMap[testsuite_key]:false;
}
global define void SetTestsuite( boolean value ) ``{
StorageMap = add( StorageMap, testsuite_key, value );
}
global define string GetDoResize()``{
return StorageMap[do_resize_key]:"NO";
}
global define void SetDoResize( string value ) ``{
StorageMap = add( StorageMap, do_resize_key, value );
}
global define string GetPartProposalMode()``{
return StorageMap[part_proposal_mode_key]:"accept";
}
global define void SetPartProposalMode( string value ) ``{
StorageMap = add( StorageMap, part_proposal_mode_key, value );
}
global define boolean GetPartProposalFirst()``{
return StorageMap[part_proposal_first_key]:true;
}
global define void SetPartProposalFirst( boolean value ) ``{
StorageMap = add( StorageMap, part_proposal_first_key, value );
}
global define boolean GetWinDevice()``{
return StorageMap[win_device_key]:false;
}
global define void SetWinDevice( boolean value ) ``{
StorageMap = add( StorageMap, win_device_key, value );
}
// Storage Constructor
global void Storage()
{
if( Mode::normal() )
{
Storage::SetPartMode( "CUSTOM" );
Storage::SetPartProposalActive( false );
}
if( Stage::initial() )
{
Storage::SetPartMode( "CUSTOM" );
Storage::SetPartProposalActive( false );
}
}
global boolean GetContVolInfo(string device, map<string, any>& info)
{
any tmp = LibStorage::ContVolInfo::new("LibStorage::ContVolInfo");
if (LibStorage::StorageInterface::getContVolInfo(sint, device, tmp) != 0)
return false;
info = $[ "ctype" : toSymbol(conv_ctype, LibStorage::ContVolInfo::swig_ctype_get(tmp)),
"cname" : LibStorage::ContVolInfo::swig_cname_get(tmp),
"cdevice" : LibStorage::ContVolInfo::swig_cdevice_get(tmp),
"vname" : LibStorage::ContVolInfo::swig_vname_get(tmp),
"vdevice" : LibStorage::ContVolInfo::swig_vdevice_get(tmp) ];
y2milestone("GetContVolInfo device:%1 info:%2", device, info);
return true;
}
global boolean IsInstallationSource(string device)
{
if (part_insts == nil)
{
part_insts = "";
if (Stage::initial())
{
string tmp = (string) SCR::Read(.etc.install_inf.Partition);
if (tmp != nil && !isempty(tmp))
{
y2milestone("IsInstallationSource .etc.install_inf.Partition:\"%1\"", tmp);
map<string, any> info = $[];
if (GetContVolInfo("/dev/" + tmp, info))
part_insts = info["vdevice"]:"";
}
}
y2milestone("IsInstallationSource part_insts:\"%1\"", part_insts);
}
return !isempty(part_insts) && device == part_insts;
}
global map<string, any> NextPartition( string disk, symbol ptype )
{
y2milestone( "NextPartition disk:%1 ptype:%2", disk, ptype );
integer pt = fromSymbol(conv_ptype,ptype);
y2milestone( "NextPartition type:%1 pt:%2", ptype, pt );
integer num = 0;
string dev = "";
integer r = LibStorage::StorageInterface::nextFreePartition( sint, disk, pt, num, dev );
if( r<0 )
y2error( "NextPartition ret %1", r );
map<string, any> ret = $[ "device" : dev, "nr" : num ];
y2milestone( "NextPartition sint ret:%1 map:%2", r, ret );
return ret;
}
global map<string, any> NextMd()
{
y2milestone("NextMd");
integer num = 0;
string dev = "";
integer r = LibStorage::StorageInterface::nextFreeMd(sint, num, dev);
if( r<0 )
y2error("NextMd ret %1", r);
map<string, any> ret = $[ "device" : dev, "nr" : num ];
y2milestone( "NextMd sint ret:%1 map:%2", r, ret );
return ret;
}
global integer MaxCylLabel( map disk, integer start_cyl )
{
integer ret = Partitions::MaxSectors(disk["label"]:"") * disk["sector_size"]:512 / 1024;
y2milestone( "MaxCylLabel val_k:%1 cyl_size:%2", ret, disk["cyl_size"]:1 );
integer cylk2 = disk["cyl_size"]:1/512;
if( cylk2<2 )
cylk2 = 2;
y2milestone( "MaxCylLabel val_k:%1 cylk2:%2", ret, cylk2 );
ret = ret*2 / cylk2 - 1;
ret = ret + start_cyl;
y2milestone( "MaxCylLabel ret:%1", ret );
return( ret );
}
/**
* Creates a new partition
*
* @param string disk
* @param string device
* @param symbol ptype (types?)
* @param integer id
* @param integer start
* @param integer len (bytes|cyls?)
* @param symbol mby (one of?)
* @return boolean if successful
*/
global boolean CreatePartition( string disk, string device, symbol ptype,
integer id, integer start, integer len,
symbol mby )
{
y2milestone( "CreatePartition disk:%1 device:%2 ptype:%3 id:%4 start:%5 len:%6 mby:%7",
disk, device, ptype, id, start, len, mby );
string cdev = "";
integer pt = fromSymbol(conv_ptype,ptype);
y2milestone( "CreatePartition type:%1 pt:%2", ptype, pt );
integer ret = LibStorage::StorageInterface::createPartition( sint, disk, pt,
start, len,
cdev );
if( device!=cdev )
y2error( "CreatePartition device:%1 cdev:%2", device, cdev );
if( ret<0 )
y2error( "CreatePartition ret %1", ret );
ret = LibStorage::StorageInterface::changePartitionId( sint, device,
id );
if( ret<0 )
y2error( "CreatePartition ret %1", ret );
integer tmp = fromSymbol( conv_mountby, mby );
LibStorage::StorageInterface::changeMountBy( sint, device, tmp );
y2milestone( "CreatePartition sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean UpdatePartition( string device, integer start, integer len )
{
y2milestone( "UpdatePartition device:%1 start:%2 len:%3",
device, start, len );
integer ret = 0;
ret = LibStorage::StorageInterface::updatePartitionArea( sint, device,
start, len );
if( ret<0 )
y2error( "UpdatePartition sint ret:%1", ret );
UpdateTargetMapDev( device );
return( ret==0 );
}
/**
* Sets a mountpoint for partition
*
* @param string device name
* @param string mount point
* @return boolean if successful
*/
global boolean SetPartitionMount( string device, string mp )
{
y2milestone( "SetPartitionMount device:%1 mp:%2", device, mp );
integer ret = 0;
ret = LibStorage::StorageInterface::changeMountPoint( sint, device, mp );
if( ret<0 )
y2error( "SetPartitionMount sint ret:%1", ret );
UpdateTargetMapDev( device );
return( ret==0 );
}
/**
* Sets whether a partition should be formatted
*
* @param string device name
* @param boolean format (yes,no)
* @param symbol filesystem
* @return boolean if successful
*/
global boolean SetPartitionFormat( string device, boolean format, symbol fs )
{
y2milestone( "SetPartitionFormat device:%1 format:%2 fs:%3", device,
format, fs );
integer ret = 0;
integer tmp = fromSymbol( FileSystems::conv_fs, fs );
y2milestone( "SetPartitionFormat fs:%1", tmp );
ret = LibStorage::StorageInterface::changeFormatVolume( sint, device,
format, tmp );
if( ret<0 )
y2error( "SetPartitionFormat sint ret:%1", ret );
UpdateTargetMapDev( device );
return( ret==0 );
}
/**
* Sets partition ID
*
* @param string device name
* @param integer ID
* @return boolean if successful
*
* @see UnchangePartitionId()
*/
global boolean SetPartitionId( string device, integer id )
{
y2milestone( "SetPartitionId device:%1 id:%2", device, id );
integer ret = 0;
ret = LibStorage::StorageInterface::changePartitionId( sint, device, id );
if( ret<0 )
y2error( "SetPartitionId sint ret:%1", ret );
UpdateTargetMapDev( device );
return( ret==0 );
}
/**
* Restores the original partition ID
*
* @param string device name
* @return boolean if succesful
*
* @see SetPartitionId()
*/
global boolean UnchangePartitionId( string device )
{
y2milestone( "UnchangePartitionId device:%1", device );
integer ret = 0;
ret = LibStorage::StorageInterface::forgetChangePartitionId( sint, device );
if( ret<0 )
y2error( "UnchangePartitionId sint ret:%1", ret );
UpdateTargetMapDev( device );
return( ret==0 );
}
/**
* Sets a new size for volume
*
* @param string device name
* @param string disk
* @param integer new_cyls (in cylinders)
* @return boolean if successful
*/
global boolean ResizePartition(string device, string disk, integer new_cyls)
{
y2milestone("ResizePartition device:%1 disk:%2 new_cyls:%3", device, disk, new_cyls);
integer ret = 0;
ret = LibStorage::StorageInterface::resizePartition(sint, device, new_cyls);
if (ret < 0)
y2error("ResizePartition sint ret:%1", ret);
UpdateTargetMapDisk (disk);
return ret == 0;
}
/**
* Sets a new size for volume
*
* @param string device name
* @param string disk
* @param integer new_size (in kBytes)
* @return boolean if successful
*/
global boolean ResizeVolume(string device, string disk, integer new_size_k)
{
y2milestone("ResizeVolume device:%1 disk:%2 new_size_k:%3", device, disk, new_size_k);
integer ret = 0;
ret = LibStorage::StorageInterface::resizeVolume(sint, device, new_size_k);
if (ret < 0)
y2error("ResizeVolume sint ret:%1", ret);
UpdateTargetMapDisk(disk);
return ret == 0;
}
global boolean SetCrypt( string device, boolean crpt, boolean format )
{
y2milestone( "SetCrypt device:%1 val:%2 format:%3", device, crpt, format );
boolean is_crypt = false;
integer ret = LibStorage::StorageInterface::getCrypt( sint, device,
is_crypt );
if( ret==0 && !format && is_crypt==crpt )
y2milestone( "SetCrypt crypt already set" );
else
{
ret = LibStorage::StorageInterface::setCrypt( sint, device, crpt );
if( ret<0 )
{
y2error( "SetCrypt sint ret:%1", ret );
if( !format && crpt )
Popup::Error( sformat(_("Could not set encryption.
System error code is %1.
The crypt password provided could be incorrect.
"), ret ));
LibStorage::StorageInterface::forgetCryptPassword( sint, device );
}
else
y2milestone( "SetCrypt sint ret:%1", ret );
}
return( ret==0 );
}
integer ChangeDescText( string dev, string txt )
{
integer ret = LibStorage::StorageInterface::changeDescText( sint, dev, txt );
return( ret );
}
global boolean ChangeVolumeProperties( map part )
{
integer ret = 0;
integer tmp = 0;
boolean changed = false;
string ts = "";
string dev = part["device"]:"";
any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
ret = LibStorage::StorageInterface::getVolume( sint, dev, vinfo );
if( ret!=0 )
y2error( "ChangeVolumeProperties device:%1 not found", dev );
map curr = $[];
if( ret==0 )
{
curr = volumeMap( vinfo, curr );
}
if( ret==0 && part["mount"]:"" != curr["mount"]:"" )
{
changed = true;
ts = part["mount"]:"";
ret = LibStorage::StorageInterface::changeMountPoint( sint, dev, ts );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && part["type"]:`unknown != `extended &&
(part["format"]:false != curr["format"]:false ||
part["used_fs"]:`none != curr["used_fs"]:`none) )
{
changed = true;
tmp = fromSymbol(FileSystems::conv_fs,part["used_fs"]:`none);
y2milestone( "ChangeVolumeProperties fs:%1 symbol:%2", tmp, part["used_fs"]:`none );
ret = LibStorage::StorageInterface::changeFormatVolume( sint, dev,
part["format"]:false,
tmp );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 &&
size(part["mount"]:"")>0 && part["fstopt"]:"" != curr["fstopt"]:"" )
{
changed = true;
ts = part["fstopt"]:"";
ret = LibStorage::StorageInterface::changeFstabOptions( sint, dev, ts );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && size(part["mount"]:"")>0 &&
part["mountby"]:`id != curr["mountby"]:`id )
{
changed = true;
tmp = fromSymbol(conv_mountby,part["mountby"]:`device);
y2milestone( "ChangeVolumeProperties mby:%1", tmp );
ret = LibStorage::StorageInterface::changeMountBy( sint, dev, tmp );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && part["label"]:"" != curr["label"]:"" )
{
changed = true;
ts = part["label"]:"";
ret = LibStorage::StorageInterface::changeLabelVolume( sint, dev, ts );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && part["format"]:false &&
convertFsOptionMapToString(part["fs_options"]:$[], `mkfs) != curr["mkfs_opt"]:"" )
{
changed = true;
ts = convertFsOptionMapToString(part["fs_options"]:$[], `mkfs);
y2milestone( "FsOption ts:%1", ts );
ret = LibStorage::StorageInterface::changeMkfsOptVolume( sint, dev, ts );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && part["format"]:false &&
convertFsOptionMapToString(part["fs_options"]:$[], `tunefs) != curr["tunefs_opt"]:"" )
{
changed = true;
ts = convertFsOptionMapToString(part["fs_options"]:$[], `tunefs);
y2milestone( "FsOption ts:%1", ts );
ret = LibStorage::StorageInterface::changeTunefsOptVolume( sint, dev, ts );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && part["enc_type"]:`none != curr["enc_type"]:`none )
{
changed = true;
SetCrypt( dev, part["enc_type"]:`none!=`none, part["format"]:false );
}
if( ret==0 && part["dtxt"]:"" != curr["dtxt"]:"" )
{
changed = true;
ret = ChangeDescText( dev, part["dtxt"]:"" );
}
if( ret==0 &&
((part["resize"]:false && part["region",1]:0 != curr["region",1]:0) ||
(part["resize"]:false != curr["resize"]:false)) )
{
changed = true;
string d = part["device"]:"";
integer i = part["region",1]:0;
if( part["resize"]:false )
{
y2milestone( "ChangeVolumeProperties resize to %1 cyl", i );
if( part["ignore_fs"]:false )
ret = LibStorage::StorageInterface::resizePartitionNoFs( sint, d, i );
else
ret = LibStorage::StorageInterface::resizePartition( sint, d, i );
}
else
ret = LibStorage::StorageInterface::forgetResizeVolume( sint, d );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 && part["change_fsid"]:false && part["fsid"]:0 != curr["fsid"]:0)
{
changed = true;
string d = part["device"]:"";
integer i = part["fsid"]:0;
y2milestone( "ChangeVolumeProperties fsid to %1", i );
ret = LibStorage::StorageInterface::changePartitionId( sint, d, i );
if( ret<0 )
y2error( "ChangeVolumeProperties sint ret:%1", ret );
else
y2milestone( "ChangeVolumeProperties sint ret:%1", ret );
}
if( ret==0 )
{
y2debug( "ChangeVolumeProperties changed:%1 part:%2", changed, part );
if( changed )
UpdateTargetMapDev( dev );
}
return( ret==0 );
}
global boolean DeleteDevice(string device)
{
y2milestone( "DeleteDevice device:%1", device );
integer ret = LibStorage::StorageInterface::removeVolume( sint, device );
if( ret<0 )
y2error( "DeleteDevice sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean DeleteLvmVg( string name )
{
y2milestone( "DeleteLvmVg name:%1", name );
integer ret = LibStorage::StorageInterface::removeLvmVg( sint, name );
if( ret<0 )
y2error( "DeleteLvmVg sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean DeleteDmraid( string name )
{
y2milestone( "DeleteDmraid name:%1", name );
integer ret = LibStorage::StorageInterface::removeDmraid( sint, name );
if( ret<0 )
y2error( "DeleteDmraid sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean DeleteMdPartCo( string name )
{
y2milestone( "DeleteMdPartCo name:%1", name );
integer ret = LibStorage::StorageInterface::removeMdPartCo( sint, name, true );
if( ret<0 )
y2error( "DeleteMdPartCo sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean CreateLvmVg( string name, integer pesize, boolean lvm2 )
{
y2milestone( "CreateLvmVg name:%1 pesize:%2 lvm2:%3", name, pesize, lvm2 );
list<string> devs = [];
integer ret = 0;
ret = LibStorage::StorageInterface::createLvmVg( sint, name, pesize/1024,
!lvm2, devs );
if( ret<0 )
y2error( "CreateLvmVg sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean CreateLvmVgWithDevs( string name, integer pesize, boolean lvm2, list<string> devs )
{
y2milestone( "CreateLvmVgWithDevs name:%1 pesize:%2 lvm2:%3 devs:%4", name, pesize, lvm2, devs );
integer ret = 0;
ret = LibStorage::StorageInterface::createLvmVg( sint, name, pesize/1024,
!lvm2, devs );
if( ret<0 )
y2error( "CreateLvmVgWithDevs sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean ExtendLvmVg( string name, string device )
{
y2milestone( "ExtendLvmVg name:%1 device:%2", name, device );
integer ret = 0;
list<string> devs = [ device ];
ret = LibStorage::StorageInterface::extendLvmVg( sint, name, devs );
if( ret<0 )
y2error( "ExtendLvmVg sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean ReduceLvmVg( string name, string device )
{
y2milestone( "ReduceLvmVg name:%1 device:%2", name, device );
integer ret = 0;
list<string> devs = [ device ];
ret = LibStorage::StorageInterface::shrinkLvmVg( sint, name, devs );
if( ret<0 )
y2error( "ReduceLvmVg sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean CreateLvmLv( string vgname, string lvname, integer sizeK,
integer stripes )
{
y2milestone("CreateLvmLv vg:%1 name:%2 sizeK:%3 stripes:%4", vgname,
lvname, sizeK, stripes);
integer ret = 0;
string dummy = "";
ret = LibStorage::StorageInterface::createLvmLv( sint, vgname, lvname,
sizeK, stripes,
dummy );
if( ret<0 )
y2error( "CreateLvmLv sint ret:%1", ret );
UpdateTargetMapDisk( "/dev/"+vgname );
return( ret==0 );
}
global boolean ChangeLvStripeSize( string vgname, string lvname,
integer stripeSize )
{
y2milestone( "ChangeLvStripeSize vg:%1 name:%2 stripeSize:%3", vgname,
lvname, stripeSize );
integer ret = 0;
string dummy = "";
ret = LibStorage::StorageInterface::changeLvStripeSize( sint, vgname,
lvname,
stripeSize );
if( ret<0 )
y2error( "ChangeLvStripeSize sint ret:%1", ret );
UpdateTargetMapDisk( "/dev/"+vgname );
return( ret==0 );
}
global boolean ChangeLvStripeCount( string vgname, string lvname,
integer stripes )
{
y2milestone( "ChangeLvStripeCount vg:%1 name:%2 stripes:%3", vgname,
lvname, stripes );
integer ret = 0;
string dummy = "";
ret = LibStorage::StorageInterface::changeLvStripeCount( sint, vgname,
lvname,
stripes );
if( ret<0 )
y2error( "ChangeLvStripeCount sint ret:%1", ret );
UpdateTargetMapDisk( "/dev/"+vgname );
return( ret==0 );
}
global boolean AddNfsVolume( string nfsdev, string opts, integer sz, string mp, boolean nfs4 )
{
y2milestone("AddNfsVolume dev:%1 opts:%2 size:%3 mp:%4 nfs4:%5", nfsdev, opts, sz, mp, nfs4);
integer ret = 0;
string dummy = "";
ret = LibStorage::StorageInterface::addNfsDevice(sint, nfsdev, opts, sz, mp, nfs4);
if( ret<0 )
y2error( "AddNfsVolume sint ret:%1", ret );
UpdateTargetMapDisk( "/dev/nfs" );
return( ret==0 );
}
global integer CheckNfsVolume(string nfsdev, string opts, boolean nfs4)
{
y2milestone("CheckNfsVolume dev:%1 opts:%2 nfs4:%3", nfsdev, opts, nfs4);
integer ret = 0;
integer sz = 0;
string dummy = "";
ret = LibStorage::StorageInterface::checkNfsDevice(sint, nfsdev, opts, nfs4, sz);
if( ret<0 )
y2error( "CheckNfsVolume sint ret:%1", ret );
else
ret = sz;
y2milestone( "CheckNfsVolume ret:%1", ret );
return( ret );
}
global boolean CreateMd( integer nr, string type )
{
y2milestone( "CreateMd nr:%1 type:%2", nr, type );
integer ret = 0;
integer tmp = conv_mdstring[type]:0;
list<string> dummy = [];
string rd = sformat("/dev/md%1", nr );
ret = LibStorage::StorageInterface::createMd( sint, rd, tmp, dummy );
if( ret<0 )
y2error( "CreateMd sint ret:%1", ret );
UpdateTargetMapDisk( "/dev/md" );
return( ret==0 );
}
global boolean CreateMdWithDevs(integer nr, symbol type, list<string> devices)
{
y2milestone( "CreateMdWithDevs nr:%1 type:%2 devices:%3", nr, type, devices );
integer ret = 0;
integer tmp = LibStorage::RAID_UNK();
foreach(integer k, symbol v, conv_mdtype["m"]:$[], {
if (v == type)
tmp = k;
});
string rd = sformat("/dev/md%1", nr );
ret = LibStorage::StorageInterface::createMd(sint, rd, tmp, devices);
if( ret<0 )
y2error( "CreateMdWithDevs sint ret:%1", ret );
UpdateTargetMap();
return ret==0;
}
global boolean ExtendMd( integer nr, string dev )
{
y2milestone( "ExtendMd nr:%1 dev:%2", nr, dev );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
ret = LibStorage::StorageInterface::extendMd( sint, rd, dev );
if( ret<0 )
y2error( "ExtendMd sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean ShrinkMd( integer nr, string dev )
{
y2milestone( "ShrinkMd nr:%1 dev:%2", nr, dev );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
ret = LibStorage::StorageInterface::shrinkMd( sint, rd, dev );
if( ret<0 )
y2error( "ShrinkMd sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean ChangeMdType( integer nr, string mdtype )
{
y2milestone( "ChangeMdType nr:%1 mdtype:%2", nr, mdtype );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
integer tmp = conv_mdstring[mdtype]:0;
ret = LibStorage::StorageInterface::changeMdType( sint, rd, tmp );
if( ret<0 )
y2error( "ChangeMdType sint ret:%1", ret );
UpdateTargetMapDev( rd );
return( ret==0 );
}
global boolean ChangeMdParity( integer nr, string ptype )
{
y2milestone( "ChangeMdParity nr:%1 parity:%2", nr, ptype );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
integer tmp = conv_parstring[ptype]:0;
ret = LibStorage::StorageInterface::changeMdParity( sint, rd, tmp );
if( ret<0 )
y2error( "ChangeMdParity sint ret:%1", ret );
UpdateTargetMapDev( rd );
return( ret==0 );
}
global boolean ChangeMdParitySymbol( integer nr, symbol ptype )
{
y2milestone( "ChangeMdParitySymbol nr:%1 parity:%2", nr, ptype );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
integer tmp = fromSymbol(conv_mdparity, ptype);
ret = LibStorage::StorageInterface::changeMdParity(sint, rd, tmp);
if( ret<0 )
y2error( "ChangeMdParitySymbol sint ret:%1", ret );
UpdateTargetMapDev( rd );
return( ret==0 );
}
global boolean ChangeMdChunk( integer nr, integer chunk )
{
y2milestone( "ChangeMdChunk nr:%1 chunk:%2", nr, chunk );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
ret = LibStorage::StorageInterface::changeMdChunk( sint, rd, chunk );
if( ret<0 )
y2error( "ChangeMdChunk sint ret:%1", ret );
UpdateTargetMapDev( rd );
return( ret==0 );
}
global integer CheckMd( integer nr )
{
y2milestone( "CheckMd nr:%1", nr );
integer ret = 0;
string rd = sformat("/dev/md%1", nr );
ret = LibStorage::StorageInterface::checkMd( sint, rd );
if( ret!=0 )
y2milestone( "CheckMd sint ret:%1", ret );
return( ret );
}
global integer ComputeMdSize(symbol md_type, list<string> devices, integer& sizeK)
{
integer ret = 0;
integer tmp = LibStorage::RAID_UNK();
foreach(integer k, symbol v, conv_mdtype["m"]:$[], {
if (v == md_type)
tmp = k;
});
ret = LibStorage::StorageInterface::computeMdSize(sint, tmp, devices, sizeK);
if( ret!=0 )
y2milestone( "ComputeMdSize sint ret:%1", ret );
return ret;
}
global string GetCryptPwd( string device )
{
string pwd="";
y2milestone( "GetCryptPwd device:%1", device );
integer ret = 0;
ret = LibStorage::StorageInterface::getCryptPassword( sint, device,
pwd );
if( ret<0 )
y2error( "GetCryptPwd sint ret:%1", ret );
else
y2milestone( "GetCryptPwd empty:%1", size(pwd)==0 );
return( pwd );
}
global boolean SetCryptPwd( string device, string pwd )
{
y2milestone( "SetCryptPwd device:%1", device );
integer ret = 0;
ret = LibStorage::StorageInterface::setCryptPassword( sint, device,
pwd );
if( ret<0 )
y2error( "SetCryptPwd sint ret:%1", ret );
else
y2milestone( "SetCryptPwd sint ret:%1", ret );
return( ret==0 );
}
global boolean ActivateCrypt( string device, boolean on )
{
y2milestone( "ActivateCrypt device:%1 on:%2", device, on );
integer ret = 0;
ret = LibStorage::StorageInterface::activateEncryption( sint, device, on );
if( ret<0 )
y2error( "ActivateCrypt ret:%1", ret );
else
y2milestone( "ActivateCrypt ret:%1", ret );
return( ret==0 );
}
global boolean NeedCryptPwd( string device )
{
boolean ret = false;
ret = LibStorage::StorageInterface::needCryptPassword( sint, device );
y2milestone( "NeedCryptPwd device:%1 ret:%2", device, ret );
return( ret );
}
global string CreateLoop( string file, boolean create, integer sizeK,
string mp )
{
y2milestone( "CreateLoop file:%1 create:%2 sizeK:%3 mp:%4", file, create,
sizeK, mp );
string dev = "";
integer ret = 0;
string pwd = GetCryptPwd( file );
ret = LibStorage::StorageInterface::createFileLoop( sint, file, !create,
sizeK, mp, pwd, dev );
if( ret<0 )
y2error( "CreateLoop sint ret:%1", ret );
LibStorage::StorageInterface::forgetCryptPassword( sint, file );
UpdateTargetMapDisk( "/dev/loop" );
y2milestone( "CreateLoop dev:%1", dev );
return( dev );
}
define void HandleModulesOnBoot( map<string,map> targetMap );
global boolean UpdateLoop( string dev, string file, boolean create,
integer sizeK )
{
y2milestone( "UpdateLoop device:%1 file:%2 create:%3 sizeK:%4",
dev, file, create, sizeK );
integer ret = LibStorage::StorageInterface::modifyFileLoop( sint, dev, file,
!create,
sizeK );
if( ret<0 )
y2error( "UpdateLoop sint ret:%1", ret );
UpdateTargetMapDisk( "/dev/loop" );
HandleModulesOnBoot( GetTargetMap() );
return( ret==0 );
}
global boolean DeleteLoop( string disk, string file, boolean remove_file )
{
y2milestone( "DeleteLoop disk:%1 file:%2 remove_file:%3", disk, file,
remove_file );
integer ret = LibStorage::StorageInterface::removeFileLoop( sint, file,
remove_file );
if( ret<0 )
y2error( "DeleteLoop sint ret:%1", ret );
UpdateTargetMapDisk( disk );
return( ret==0 );
}
global string DefaultDiskLabel(string disk)
{
string label = LibStorage::StorageInterface::defaultDiskLabel(sint, disk);
y2milestone("DefaultDiskLabel disk:%1 label:%2", disk, label);
return label;
}
/**
* Delete the partition table and disk label of device
* @param string the disk to deleted the partition table from
* @return boolean
*/
global boolean DeletePartitionTable(string disk)
{
y2milestone("DeletePartitionTable disk:%1", disk);
string label = DefaultDiskLabel(disk);
integer ret = LibStorage::StorageInterface::destroyPartitionTable(sint, disk, label);
if( ret<0 )
y2error( "DeletePartitionTable sint ret:%1", ret );
UpdateTargetMap();
return( ret==0 );
}
global boolean CreatePartitionTable(string disk, string label)
{
y2milestone("CreatePartitionTable %1 label:%2", disk, label);
integer ret = LibStorage::StorageInterface::destroyPartitionTable(sint, disk, label);
if (ret < 0)
y2error("CreatePartitionTable sint ret:%1", ret);
UpdateTargetMap();
return ret == 0;
}
global symbol GetMountBy( string device );
/**
* Set the flag if a disk needs to be initialized
* @param string the disk to be changed
* @return boolean
*/
global define boolean InitializeDisk(string disk, boolean value)
``{
boolean rbool = true;
y2milestone( "InitializeDisk %1 value %2", disk, value );
integer ret =
LibStorage::StorageInterface::initializeDisk( sint, disk, value );
if( ret<0 )
{
y2error( "InitializeDisk sint ret:%1", ret );
rbool = false;
}
if( rbool && value )
{
map<string,any> d = GetDisk( GetTargetMap(), disk );
y2milestone( "d:%1", d );
rbool = CreatePartition( disk, disk+"1", `primary,
Partitions::fsid_native,
0, d["cyl_count"]:1,
GetMountBy( disk+"1" ) );
if( !rbool )
y2error( "InitializeDisk create failed" );
}
UpdateTargetMapDisk( disk );
return( rbool );
}
global boolean IsPartType(symbol t)
{
return t == `CT_DMRAID || t == `CT_DMMULTIPATH || t == `CT_DISK || t == `CT_MDPART;
}
boolean CreateAny( symbol ctype, map d, map& p )
{
boolean ret = true;
if( IsPartType(ctype) )
{
ret = Storage::CreatePartition( d["device"]:"", p["device"]:"",
p["type"]:`primary,
p["fsid"]:Partitions::fsid_native,
p["region",0]:0, p["region",1]:0,
p["mountby"]:GetMountBy( p["device"]:"" ) );
}
else if( ctype == `CT_MD )
{
ret = Storage::CreateMd( p["nr"]:0, p["raid_type"]:"raid1" );
if( ret && haskey( p, "chunk_size" ))
Storage::ChangeMdChunk( p["nr"]:0, p["chunk_size"]:4 );
if( ret && p["raid_type"]:""=="raid5" &&
haskey( p, "parity_algorithm" ))
Storage::ChangeMdParity( p["nr"]:0,
p["parity_algorithm"]:"" );
foreach( string d, p["devices"]:[],
``{ret=Storage::ExtendMd( p["nr"]:0, d )&&ret;});
}
else if( ctype == `CT_LOOP )
{
y2milestone( "CreateAny Loop p:%1", p );
string dev = Storage::CreateLoop( p["fpath"]:"", p["create_file"]:false,
p["size_k"]:0, p["mount"]:"" );
ret = size(dev)>0;
if( ret )
p["device"] = dev;
}
else if( ctype == `CT_LVM )
{
ret = Storage::CreateLvmLv( d["name"]:"", p["name"]:"", p["size_k"]:0,
p["stripes"]:1 );
if( ret && p["stripes"]:1>1 && p["stripesize"]:0>0 )
{
Storage::ChangeLvStripeSize( d["name"]:"", p["name"]:"",
p["stripesize"]:0 );
}
}
else if( ctype == `CT_NFS )
{
ret = Storage::AddNfsVolume( p["device"]:"", p["fstopt"]:"", p["size_k"]:0,
p["mount"]:"", p["used_fs"]:`nfs == `nfs4 );
}
y2milestone( "CreateAny ret:%1", ret );
return( ret );
}
boolean IsEfiPartition(map p)
{
boolean ret = false;
map<symbol, any> resize_info = $[];
map<symbol, any> content_info = $[];
if (GetFreeInfo(p["device"]:"", false, resize_info, true, content_info, true) &&
content_info[`efi]:false)
{
ret = true;
}
y2milestone("IsEfiPartition ret:%1", ret);
return ret;
}
/**
* Search in the list partitions for windows partitions and add the key
* "mount" to the found windows partitions.
* @parm partitions the partitions list
* @parm primary handle primary or logical partitions
* @return list new partitions with windows mountpoints
*/
void AddMountPointsForWinParts( list<map> partitions, boolean primary,
integer max_prim, integer& foreign_nr )
{
if( !Arch::i386 () && !Arch::ia64 () && !Arch::x86_64 () )
return;
string foreign_ids = "CDEFGHIJKLMNOPQRSTUVW";
foreach(map partition, partitions,
``{
map new_partition = partition;
integer fsid = partition["fsid"]:Partitions::fsid_native;
integer partnum = 0;
if( haskey( partition, "nr") && is( partition["nr"]:(any)0, integer ) )
{
partnum = partition["nr"]:0;
}
if( !haskey( partition, "mount") &&
!partition["delete"]:false &&
((partnum<=max_prim)==primary) &&
foreign_nr < 24 &&
Partitions::IsDosWinNtPartition(fsid) &&
(!Arch::ia64() || (!IsEfiPartition(partition) &&
partition["size_k"]:0 >= 1024*1024)) &&
contains( [`vfat, `ntfs], partition["used_fs"]:`none ))
{
new_partition["fstopt"] =
FileSystems::DefaultFstabOptions(partition);
if( contains( Partitions::fsid_dostypes, fsid ))
{
new_partition["mount"] =
"/dos/" + substring (foreign_ids, foreign_nr, 1);
foreign_nr = foreign_nr + 1;
}
else
{
new_partition["mount"] =
"/windows/" + substring (foreign_ids, foreign_nr, 1);
foreign_nr = foreign_nr + 1;
}
ChangeVolumeProperties( new_partition );
y2milestone( "win part %1", new_partition );
}
});
};
global void AddMountPointsForWin( map<string, map> targets )
{
y2milestone( "AddMountPointsForWin called" );
integer foreign_nr = 0;
foreach(string disk, map data, targets,
``{
if( !data["hotpluggable"]:false &&
data["used_by_type"]:`UB_NONE == `UB_NONE )
AddMountPointsForWinParts( data["partitions"]:[], true,
data["max_primary"]:4, foreign_nr );
});
foreach(string disk, map data, targets,
``{
if( !data["hotpluggable"]:false &&
data["used_by_type"]:`UB_NONE == `UB_NONE )
AddMountPointsForWinParts( data["partitions"]:[], false,
data["max_primary"]:4, foreign_nr );
});
}
/**
* Removes ... maps to ...
*
* @param string device name
*/
global void RemoveDmMapsTo( string device )
{
y2milestone( "RemoveDmMapsTo device:%1", device );
if (!InitLibstorage(false))
return;
LibStorage::StorageInterface::removeDmTableTo( sint, device );
}
global boolean CheckSwapable( string dev )
{
if (Mode::test())
return true;
string cmd = "/sbin/swapon --fixpgsz " + dev;
boolean ok = (integer)SCR::Execute(.target.bash, cmd )==0;
if( ok )
{
cmd = "/sbin/swapoff " + dev;
SCR::Execute(.target.bash, cmd );
}
y2milestone( "CheckSwapable dev:%1 ret:%2", dev, ok );
return( ok );
}
/**
* mark swap-partitions with pseudo Mountpoint swap in targetMap
* @param target Disk map
* @return map<string,map> modified target
*/
map<string, map> AddSwapMp( map<string, map> target )
{
list<string> swaps = SwappingPartitions();
y2milestone( "AddSwapMp swaps %1", swaps );
foreach(string diskdev, map disk, target,
``{
disk["partitions"] = maplist(map part, disk["partitions"]:[],
``{
if( (Stage::initial() &&
!Partitions::IsDosWinNtPartition(part["fsid"]:0) &&
part["detected_fs"]:`unknown==`swap &&
!part["old_swap"]:false &&
search( diskdev, "/dev/evms" )!=0 ) ||
(contains( swaps, part["device"]:"" )))
{
y2milestone( "AddSwapMp %1", part );
boolean ok = true;
if( !contains( swaps, part["device"]:"" ))
{
string dev = part["device"]:"";
if( !isempty(part["crypt_device"]:""))
dev = part["crypt_device"]:"";
ok = CheckSwapable( dev );
y2milestone( "AddSwapMp initial ok:%1", ok );
}
if( ok )
{
part["mount"] = "swap";
ChangeVolumeProperties( part );
y2milestone( "AddSwapMp %1", part );
}
}
return( part );
});
target[diskdev] = disk;
});
return target;
}
global boolean CheckCryptOk( string dev, string fs_passwd, boolean silent,
boolean erase )
{
integer i = LibStorage::StorageInterface::verifyCryptPassword( sint, dev, fs_passwd, erase );
if( i!=0 && !silent )
Popup::Error( sformat(_("Could not set encryption.
System error code is %1.
The crypt password provided could be incorrect.
"), i ));
y2milestone( "CheckCryptOk dev:%1 pwlen:%2 ret:%3",
dev, size(fs_passwd), i==0 );
return( i==0 );
}
global boolean RescanCrypted()
{
boolean ret = LibStorage::StorageInterface::rescanCryptedObjects( sint );
y2milestone( "RescanCrypted ret:%1", ret );
return( ret );
}
global boolean CheckEncryptionPasswords( string pw1, string pw2,
integer min_length,
boolean empty_allowed)
{
if (pw1 != pw2)
{
// popup text
Popup::Message(_("The first and the second version
of the password do not match.
Try again."));
return false;
}
if (isempty(pw1))
{
if (!empty_allowed)
{
// popup text
Popup::Message(_("You did not enter a password.
Try again.
"));
return false;
}
}
else
{
if (size(pw1) < min_length)
{
// popup text
Popup::Message(sformat(_("The password must have at least %1 characters.
Try again.
"), min_length));
return false;
}
string allowed_chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#* ,.;:._-+!$%&/|\?{[()]}@^\\<>";
if (findfirstnotof(pw1, allowed_chars) != nil)
{
// popup text
Popup::Message(_("The password may only contain the following characters:
0..9, a..z, A..Z, and any of \"@#* ,.;:._-+!$%&/|\?{[()]}^\\<>\".
Try again."));
return false;
}
}
return true;
}
global string PasswdPopup( string helptxt, string header, string label,
boolean pw2, integer minpwlen, boolean tmpcrypt )
{
term ad = `Empty();
if( pw2 )
ad = `VBox(
`VSpacing(0.5),
`HBox(
`Password(`id(`pw2), `opt(`hstretch),
// Label: get same password again for verification
// Please use newline if label is longer than 40 characters
_("Reenter the password for &verification:"), ""),
`HSpacing(13))
);
UI::OpenDialog(
`opt(`decorated ),
`HBox(
`HWeight(3, `RichText( helptxt ) ),
`HWeight(6, `VBox(
`VSpacing(0.3),
`HBox(
`HSpacing(1),
`Heading(header),
`HSpacing(1)
),
`VSpacing(1),
`HBox(
`HSpacing(4),
`VBox(
// label text
`Label(label),
`VSpacing(),
`HBox(
`Password(`id(`pw1), `opt(`hstretch),
// Label: get password for encrypted volume
// Please use newline if label is longer than 40 characters
_("&Enter encryption password:"), ""),
`HSpacing(13)),
ad),
`HSpacing(4)
),
`VSpacing(2),
`ButtonBox(
`PushButton(`id(`ok), `opt(`default), Label::OKButton()),
`PushButton(`id(`cancel), Label::CancelButton())
),
`VSpacing(0.5)
)
)
));
string ret = "";
string password = "";
symbol widget = nil;
repeat
{
// Clear password fields on every round.
UI::ChangeWidget(`id(`pw1), `Value, "");
if( pw2 )
UI::ChangeWidget(`id(`pw2), `Value, "");
UI::SetFocus(`id(`pw1));
widget = (symbol) UI::UserInput();
switch (widget)
{
case `ok:
password = (string) UI::QueryWidget(`id(`pw1), `Value);
string tmp = password;
if( pw2 )
tmp = (string) UI::QueryWidget(`id(`pw2), `Value);
if (!Storage::CheckEncryptionPasswords( password, tmp,
minpwlen, tmpcrypt))
widget = `again;
else
ret = password;
break;
}
} until (widget == `cancel || widget == `ok);
UI::CloseDialog();
if( widget == `ok )
ret = password;
return( ret );
}
boolean CryptVolPopup( list<string> dev1, list<string> dev2 )
{
term button_box = `ButtonBox(
`PushButton( `id(`yes), `opt(`okButton), _("Provide Password")),
`PushButton( `id(`no_button), `opt(`default, `cancelButton), Label::CancelButton())
);
map display_info = UI::GetDisplayInfo();
boolean has_image_support = display_info["HasImageSupport"]:false;
term ad = `Empty();
if( size(dev2)>0 )
ad = `VBox(
`Left( `Label( _(
"The following encrypted volumes are already available."))),
`Left(`RichText(HTML::List(sort(dev2)))),
`VSpacing(0.2)
);
term icon = has_image_support ? `Top (`Image(Icon::IconPath ("question")))
: `Empty();
term layout =
`VBox (
`VSpacing (0.4),
`HBox (
icon,
`HSpacing (1),
`VBox (
`Left (`Heading (_("Encrypted Volume Activation"))),
`VSpacing(0.2),
`Left( `Label( _(
"The following volumes contain an encryption signature but the
passwords are not yet known.
The passwords need to be known if the volumes are needed either
during an update or if they contain an encrypted LVM physical volume."))),
`VSpacing(0.2),
`Left(`RichText(HTML::List(sort(dev1)))),
`VSpacing(0.2),
ad,
`Left(`Label( _("Do you want to provide crypt passwords?"))),
button_box
)
)
);
UI::OpenDialog(layout);
symbol ret = (symbol) UI::UserInput();
UI::CloseDialog();
y2milestone( "symbol:%1", ret );
return ret == `yes;
}
map GetCryptLists( map<string, map> target )
{
list<map> ac_cr = [];
list<map> in_cr = [];
foreach( string k, map m, target,
``{
list<map> tmp = filter( map p, m["partitions"]:[],
``(p["enc_type"]:`none==`luks ));
in_cr = (list<map>)merge( in_cr,
filter( map p, tmp,
``(isempty(p["crypt_device"]:""))));
ac_cr = (list<map>)merge( ac_cr,
filter( map p, tmp,
``(!isempty(p["crypt_device"]:""))));
});
y2milestone( "GetCryptLists inactive:%1", in_cr );
y2milestone( "GetCryptLists active:%1", ac_cr );
map ret = $[];
ret["active"] = maplist( map p, ac_cr, ``(p["device"]:""));
ret["inactive"] = maplist( map p, in_cr, ``(p["device"]:""));
y2milestone( "ret:%1", ret );
return( ret );
}
map<string, map> AskCryptPasswords( map<string, map> target )
{
map crvol = GetCryptLists( target );
boolean ret = true;
boolean rescan_done = false;
// text in help field
string helptext = _(
"Enter encryption password for any of the
devices in the locked devices list.
Password will be tried for all devices.");
// header text
string header = _("Enter Encryption Password");
while( size(crvol["inactive"]:[])>0 && ret )
{
ret = CryptVolPopup( crvol["inactive"]:[], crvol["active"]:[] );
y2milestone( "ret:%1", ret );
if( ret )
{
// label text, multiple device names follow
string label = _("Please provide password for any of the following devices:");
if( size(crvol["inactive"]:[])==1 )
// label text, one device name follows
label = _("Please provide password for the following device:");
foreach( string s, crvol["inactive"]:[],
``{
label = label + sformat("\n%1", s );
});
string pw = PasswdPopup( helptext, header, label, false, 1, false );
if( size(pw)>0 )
{
UI::OpenDialog( `opt(`decorated),
`VBox(
`VSpacing(1),
`HBox(`HSpacing(1),
`Label(_("Trying to unlock encrypted volumes...")),
`HSpacing(1)),
`VSpacing(1)));
boolean unlock = false;
list<string> rl = [];
foreach( string d, crvol["inactive"]:[],
``{
if( CheckCryptOk( d, pw, true, false ) &&
SetCryptPwd( d, pw ) &&
SetCrypt( d, true, false ) &&
ActivateCrypt( d, true ) )
{
y2milestone( "AskCryptPasswords activated %1", d );
unlock = true;
crvol["active"] = add( crvol["active"]:[], d );
rl = add( rl, d );
}
});
UI::CloseDialog();
if( !unlock )
{
Popup::Error( _("Password did not unlock any volume."));
}
else
{
crvol["inactive"] = filter( string s, crvol["inactive"]:[],
``(!contains(rl,s)));
RescanCrypted();
rescan_done = true;
}
}
}
}
if( rescan_done )
{
StorageMap[targets_key] = target;
UpdateTargetMap();
target = StorageMap[targets_key]:$[];
}
return( target );
}
map<string, map> AddProposalName(map<string, map> target_map)
{
integer ide_disk_count = 0;
integer scsi_disk_count = 0;
integer generic_disk_count = 0;
integer dm_raid_count = 0;
integer md_raid_count = 0;
return mapmap(string device, map disk, target_map, {
string s = Storage::KByteToHumanString(disk["size_k"]:0);
switch (disk["type"]:`CT_UNKNOWN)
{
case `CT_DISK:
{
string proposal_name = "";
string bus = disk["bus"]:"";
if (bus == "IDE") {
ide_disk_count = ide_disk_count + 1;
proposal_name = sformat("%1. ", ide_disk_count) + _("IDE Disk");
} else if (bus == "SCSI") {
scsi_disk_count = scsi_disk_count + 1;
proposal_name = sformat("%1. ", scsi_disk_count) + _("SCSI Disk");
} else {
generic_disk_count = generic_disk_count + 1;
proposal_name = sformat("%1. ", generic_disk_count) + _("Disk");
}
proposal_name = proposal_name + ", " + s + ", " + device + ", ";
if (!isempty(disk["vendor"]:""))
proposal_name = proposal_name + disk["vendor"]:"" + "-";
proposal_name = proposal_name + disk["model"]:"";
disk["proposal_name"] = proposal_name;
}
break;
case `CT_DMRAID:
{
dm_raid_count = dm_raid_count + 1;
string proposal_name = sformat("%1. ", dm_raid_count) + _("DM RAID");
proposal_name = proposal_name + ", " + s + ", " + device;
disk["proposal_name"] = proposal_name;
}
break;
case `CT_MDPART:
{
md_raid_count = md_raid_count + 1;
string proposal_name = sformat("%1. ", md_raid_count) + _("MD RAID");
proposal_name = proposal_name + ", " + s + ", " + device;
disk["proposal_name"] = proposal_name;
}
break;
}
return $[ device : disk ];
});
}
/**
* Returns a system target map.
*
* @return map <string,map> target map
*
* @struct
* $[
* ... ?
* ]
*/
global map<string, map> GetTargetMap()
{
if (!InitLibstorage(false))
return nil;
map<string,map> tmp = $[];
boolean changed = false;
if (Mode::test())
{
foreach(map c, conts, {
tmp[c["device"]:""] = getContainerInfo(c);
});
StorageMap[targets_key] = tmp;
if (!probe_done)
{
probe_done = true;
changed = true;
}
}
else if( !probe_done && !Mode::config() )
{
map<string,string> bios_id_raid = $[];
y2milestone ("probing StorageDevices" );
map<string,string> rename = $[];
tmp = StorageDevices::Probe(true);
foreach( string dev, map disk, tmp,
``{
map dtmp = Storage::GetDiskPartitionTg( dev, $[] )[0]:$[];
y2milestone( "probing dev %1 disk %2", dev, dtmp );
if( search( dev, "/dev/dm-" )==0 || search( dev, "/dev/md" )==0 )
{
if( size(disk["bios_id"]:"")>0 )
bios_id_raid[dev] = disk["bios_id"]:"";
}
else if( size(dtmp["disk"]:"")>0 && dev != dtmp["disk"]:"" )
{
rename[dev] = dtmp["disk"]:"";
y2milestone( "probing rename %1", rename );
}
});
tmp = filter( string dev, map disk, tmp,
``(search( dev, "/dev/dm-" )!=0));
tmp = filter( string dev, map disk, tmp,
``(search( dev, "/dev/md" )!=0));
if( size(rename)>0 )
{
foreach( string old, string new, rename,
``{
if( haskey( tmp, old ))
{
tmp[new] = tmp[old]:$[];
tmp = remove( tmp, old );
tmp[new,"device"] = new;
y2milestone( "probing old:%1 new:%2", old, tmp[new]:$[] );
}
});
}
y2milestone ("probing done" );
if( size(tmp)>0 )
{
probe_done = true;
changed = true;
foreach (string dev, map disk, tmp, {
tmp[dev] = getDiskInfo(dev, disk);
if( disk["dasdfmt"]:false )
Storage::InitializeDisk( dev, true );
});
foreach (map c, conts, {
if( c["type"]:`CT_UNKNOWN!=`CT_DISK )
tmp[c["device"]:""] = getContainerInfo( c );
});
if (!isempty(bios_id_raid))
{
y2milestone( "bios_id_raid:%1", bios_id_raid );
foreach( string dm, string bios, bios_id_raid, {
integer pos = findfirstof( dm, "0123456789" );
integer minor = tointeger( substring( dm, pos ));
y2milestone( "pos:%1 minor:%2", pos, minor );
foreach (string dev, map c, tmp, {
if (c["type"]:`CT_UNKNOWN == `CT_DMRAID && c["minor"]:0 == minor)
{
y2milestone("addind bios_id %1 to %2", bios, dev);
tmp[dev, "bios_id"] = bios;
}
if (c["type"]:`CT_UNKNOWN == `CT_MDPART && c["device"]:"" == dm)
{
y2milestone("addind bios_id %1 to %2", bios, dev);
tmp[dev, "bios_id"] = bios;
}
});
});
}
if (Stage::initial())
{
tmp = AddProposalName(tmp);
tmp = AskCryptPasswords( tmp );
}
StorageMap[targets_key] = tmp;
}
}
if( changed )
{
tmp = StorageMap[targets_key]:$[];
SCR::Write(.target.ycp, Storage::SaveDumpPath("targetMap_i"), tmp );
if( !Mode::autoinst() )
{
y2milestone ("AddSwapMp" );
tmp = AddSwapMp( tmp );
}
CreateTargetBackup( "initial" );
if( (Stage::initial() || Mode::repair()) && !Mode::autoinst() )
{
AddMountPointsForWin( tmp );
}
StorageMap[targets_key] = GetTargetMap();
SCR::Write(.target.ycp, Storage::SaveDumpPath("targetMap_ii"), tmp );
y2milestone ("changed done" );
}
map<string, map> ret = StorageMap[targets_key]:$[];
if( changed )
y2milestone("GetTargetMap changed:%1", changed );
else
y2debug("GetTargetMap changed:%1", changed );
foreach( string k, map m, ret,
``{
if (changed)
y2milestone("GetTargetMap %1:%2", k, m);
else
y2debug("GetTargetMap %1:%2", k, m);
});
return ret;
}
global list<string> GetAffectedDevices( string dev )
{
list<string> r = [];
integer ret = LibStorage::StorageInterface::getRecursiveUsing(sint,dev,r);
y2milestone( "GetAffectedDevices dev:%1 ret:%2 r:%3", dev, ret, r );
return( r );
}
global void SetRecursiveRemoval( boolean val )
{
y2milestone( "SetRecursiveRemoval val:%1", val );
LibStorage::StorageInterface::setRecursiveRemoval( sint, val );
}
global boolean GetRecursiveRemoval()
{
return( LibStorage::StorageInterface::getRecursiveRemoval( sint ));
}
global define void SetTargetMap( map<string,map> target )
{
y2milestone( "SetTargetMap" );
if( !GetRecursiveRemoval() )
SetRecursiveRemoval(true);
//SCR::Write(.target.ycp, Storage::SaveDumpPath("targetMap_set_"+sformat("%1",count)), target );
//count = count+1;
CreateTargetBackup("tmp_set");
map<string,map> tg = GetTargetMap();
list<string> keys = maplist( string k, any e, target, ``(k));
foreach( string k, keys,
``{
if( target[k,"delete"]:false && haskey( tg, k ) )
{
if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM )
{
DeleteLvmVg( target[k,"name"]:"" );
target[k,"delete"] = false;
}
else if( target[k,"type"]:`CT_UNKNOWN==`CT_DMRAID )
{
DeleteDmraid( k );
target[k,"delete"] = false;
}
}
});
keys = maplist( string k, any e, target, ``(k));
y2milestone( "SetTargetMap keys %1", keys );
list<string> t1 = filter( string k, keys,
``(!target[k,"delete"]:false&&
!target[k,"create"]:false));
foreach( string k, t1,
``{
list<map> dps = filter( map p, target[k,"partitions"]:[],
``(!p["create"]:false&&!p["delete"]:false));
if( size(dps)>0 )
{
foreach( map p, dps,
``{
if( p["type"]:`primary != `extended || p["resize"]:false )
ChangeVolumeProperties( p );
});
}
});
keys = maplist( string k, any e, tg, ``(k));
keys = sort( string a, string b, keys,
``( type_order[tg[a,"type"]:`CT_UNKNOWN]:9 >
type_order[tg[b,"type"]:`CT_UNKNOWN]:9 ));
y2milestone( "SetTargetMap keys %1", keys );
foreach( string k, keys,
``{
list<map> dps = filter( map p, tg[k,"partitions"]:[],
``(p["create"]:false));
if( size(dps)>1 && haskey( dps[0]:$[], "nr" ))
{
dps = sort( map a, map b, dps, ``(a["nr"]:0>b["nr"]:0));
y2milestone( "SetTargetMap dps:%1", dps );
}
foreach( map p, dps, ``{DeleteDevice( p["device"]:"" );});
if( tg[k,"create"]:false )
{
if( tg[k,"type"]:`CT_UNKNOWN==`CT_LVM )
DeleteLvmVg( tg[k,"name"]:"" );
}
else if( !tg[k,"delete"]:false )
{
if( tg[k,"type"]:`CT_UNKNOWN==`CT_LVM &&
size(target[k,"devices_add"]:[])>0 )
{
list<string> ls = target[k,"devices_add"]:[];
foreach( string d, ls,
``{Storage::ReduceLvmVg( target[k,"name"]:"", d );});
}
}
});
keys = maplist( string k, any e, target, ``(k));
keys = sort( string a, string b, keys,
``( type_order[target[a,"type"]:`CT_UNKNOWN]:9 >
type_order[target[b,"type"]:`CT_UNKNOWN]:9 ));
y2milestone( "SetTargetMap keys %1", keys );
foreach( string k, keys,
``{
list<map> dps = filter( map p, target[k,"partitions"]:[],
``(p["delete"]:false));
if( size(dps)>1 && haskey( dps[0]:$[], "nr" ))
{
dps = sort( map a, map b, dps, ``(a["nr"]:0>b["nr"]:0));
}
foreach( map p, dps,
``{
if( size(p["dtxt"]:"")>0 )
ChangeDescText( p["device"]:"", p["dtxt"]:"" );
DeleteDevice( p["device"]:"" );
});
if( target[k,"delete"]:false )
{
if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM )
DeleteLvmVg( target[k,"name"]:"" );
else if( target[k,"type"]:`CT_UNKNOWN==`CT_DISK )
DeletePartitionTable( k );
else if( target[k,"type"]:`CT_UNKNOWN==`CT_DMRAID )
DeleteDmraid( k );
}
if( target[k,"del_ptable"]:false &&
IsPartType( target[k,"type"]:`CT_UNKNOWN ) )
{
DeletePartitionTable( k );
}
});
keys = maplist( string k, any e, target, ``(k));
keys = sort( string a, string b, keys,
``( type_order[target[a,"type"]:`CT_UNKNOWN]:9 <
type_order[target[b,"type"]:`CT_UNKNOWN]:9 ));
y2milestone( "SetTargetMap keys %1", keys );
foreach( string k, keys,
``{
if( target[k,"create"]:false )
{
if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM )
{
CreateLvmVg( target[k,"name"]:"", target[k,"pesize"]:0,
target[k,"lvm2"]:true );
list<string> ls =
(list<string>)union( target[k,"devices"]:[],
target[k,"devices_add"]:[] );
foreach( string d, ls,
``{Storage::ExtendLvmVg( target[k,"name"]:"", d );});
}
}
if( !target[k,"delete"]:false && !target[k,"create"]:false )
{
if( target[k,"type"]:`CT_UNKNOWN==`CT_LVM &&
size(target[k,"devices_add"]:[])>0 )
{
list<string> ls = target[k,"devices_add"]:[];
foreach( string d, ls,
``{Storage::ExtendLvmVg( target[k,"name"]:"", d );});
}
}
list<map> dps = filter( map p, target[k,"partitions"]:[],
``(!p["delete"]:false&&p["create"]:false) );
if( size(dps)>1 && haskey( dps[0]:$[], "nr" ))
dps = sort( map a, map b, dps, ``(a["nr"]:0<b["nr"]:0));
foreach( map p, dps,
``{
CreateAny( target[k,"type"]:`CT_UNKNOWN, target[k]:$[], p );
if( p["type"]:`primary != `extended )
ChangeVolumeProperties( p );
});
});
boolean changed = !EqualBackupStates( "tmp_set", "", true );
y2milestone( "SetTargetMap changed:%1", changed );
if( changed )
UpdateChangeTime();
DisposeTargetBackup("tmp_set");
y2milestone( "SetTargetMap ChangeTime %1", GetTargetChangeTime() );
};
/**
* Rereads the system target map and returns it
*
* @return map <string,map> target map
*
* @see GetTargetMap();
*/
global map<string, map> ReReadTargetMap()
{
boolean need_reread = sint != nil;
if (!InitLibstorage(false))
return nil;
y2milestone("start reread need_reread:%1", need_reread);
probe_done = false;
if (need_reread)
LibStorage::StorageInterface::rescanEverything(sint);
conts = getContainers();
return GetTargetMap();
}
/**
* Apply storage changes
*
* @return integer
*/
global integer CommitChanges()
{
y2milestone( "CommitChanges" );
integer ret = LibStorage::StorageInterface::commit( sint );
if( ret<0 )
y2error( "CommitChanges sint ret:%1", ret );
Storage::UpdateTargetMap();
return( ret );
}
global string DeviceMounted( string dev )
{
list<string> ret = [];
LibStorage::StorageInterface::checkDeviceMounted( sint, dev, ret );
if (!isempty(ret))
y2milestone("DeviceMounted %1 at %2", dev, ret[0]:"");
return ret[0]:"";
}
/**
* Umounts a device
*
* @param string device name
* @return boolean if successful
*
* @see Mount()
*/
global boolean Umount( string dev )
{
boolean ret = LibStorage::StorageInterface::umountDevice( sint, dev );
y2milestone( "Umount %1 ret %2", dev, ret );
return( ret );
}
/**
* Mounts a device
*
* @param string device name
* @param string mount point
* @param fstopt mount options
* @return boolean if successful
*
* @see Umount()
*/
global boolean MountOpt( string dev, string mp, string fstopt )
{
boolean ret = LibStorage::StorageInterface::mountDeviceRo( sint, dev, mp,
fstopt );
y2milestone( "MountOpt %1 to %2 with %3 ret %4", dev, mp, fstopt, ret );
return( ret );
}
/**
* Mounts a device
*
* @param string device name
* @param string mount point
* @return boolean if successful
*
* @see Umount()
*/
global boolean Mount( string dev, string mp )
{
return( MountOpt( dev, mp, "" ) );
}
boolean DetectHomeFs( map p )
{
y2milestone( "DetectHomeFs p:%1", p );
boolean ret = false;
list<symbol> poss_fs = [ `ext2, `ext3, `ext4, `btrfs, `reiser, `xfs, `jfs ];
string device = p["device"]:"";
if( !p["create"]:false && contains( poss_fs, p["detected_fs"]:`unknown ) &&
!isempty(device) )
{
map<symbol, any> resize_info = $[];
map<symbol, any> content_info = $[];
if (GetFreeInfo(device, false, resize_info, true, content_info, true) &&
content_info[`homes]:0 > 0)
{
ret = true;
}
}
y2milestone("DetectHomeFs device:%1 ret:%2", device, ret);
return ret;
}
global define map SetVolOptions( map p, string mnt, symbol fs, string fs_opts,
string fstab_opts, string label )
{
y2milestone( "SetVolOptions p:%1", p );
y2milestone( "SetVolOptions mount:%1 fs:%2 fs_opt:%3 fst_opt:%4 label:%5",
mnt, fs, fs_opts, fstab_opts, label );
map ret = p;
if( size(mnt)>0 )
ret["mount"] = mnt;
if( fs!=nil && fs!=`unknown )
ret["used_fs"] = fs;
else
{
if( mnt==Partitions::BootMount() )
ret["used_fs"] = Partitions::DefaultBootFs();
else
ret["used_fs"] = Partitions::DefaultFs();
}
if( ret["used_fs"]:`unknown == `unknown ||
ret["used_fs"]:`unknown == `none ||
ret["used_fs"]:`unknown == `hfs ||
ret["used_fs"]:`unknown == `hfsplus )
ret["format"] = false;
else
ret["format"] = true;
if( ret["format"]:false && !ret["create"]:false &&
ret["detected_fs"]:`unknown != `unknown && mnt=="/home" )
{
boolean lvm = p["type"]:`primary == `lvm;
if( ( lvm && ret["name"]:""=="home") ||
(!lvm && DetectHomeFs(ret)))
{
ret["format"] = false;
if( ret["used_fs"]:`unknown!=ret["detected_fs"]:`unknown )
{
ret["used_fs"] = ret["detected_fs"]:`unknown;
fstab_opts = FileSystems::DefaultFstabOptions(ret);
}
}
}
if( ret["format"]:false && !ret["create"]:false &&
ret["detected_fs"]:`unknown == `swap && mnt=="swap" )
{
ret["format"] = false;
ret["used_fs"] = `swap;
}
if( size(fstab_opts)>0 )
ret["fstopt"] = fstab_opts;
else
ret["fstopt"] = FileSystems::DefaultFstabOptions( ret );
if( size(fs_opts)>0 )
ret["fs_options"] =
convertStringToFsOptionMap( fs_opts, ret["used_fs"]:`unknown, `mkfs );
else
ret["fs_options"] = FileSystems::DefaultFormatOptions( ret );
if( size(label)>0 )
ret["label"] = label;
else if( size(ret["label"]:"")>0 && ret["format"]:false )
ret["label"] = "";
y2milestone( "SetVolOptions ret:%1", ret );
return( ret );
}
global boolean CanEdit( map p, boolean verbose )
{
boolean ret = true;
if( Stage::initial() )
{
if( !p["create"]:false && !p["inactive"]:false &&
p["mount"]:""=="swap" )
{
ret = false;
y2milestone( "CanEdit p:%1", p );
if( verbose )
{
string txt = sformat( _("
Device %1 cannot be modified because it contains activated swap
that is needed to run the installation.
"), p["device"]:"" );
Popup::Message( txt );
}
}
if (IsInstallationSource(p["device"]:""))
{
ret = false;
if( verbose )
{
string txt = sformat( _("
Device %1 cannot be modified because it contains the installation
data needed to perform the installation.
"), p["device"]:"" );
Popup::Message( txt );
}
}
}
y2milestone( "CanEdit dev:%1 verbose:%2 ret:%3", p["device"]:"",
verbose, ret );
return( ret );
}
global boolean CanDelete( map p, map disk, boolean verbose )
{
string txt = "";
boolean ret = CanEdit( p, false );
if( !ret && verbose )
{
if( p["mount"]:""=="swap" )
{
txt = sformat( _("
Device %1 cannot be removed because it contains activated swap
that is needed to run the installation.
"), p["device"]:"" );
}
else
{
txt = sformat( _("
Device %1 cannot be removed because it contains the installation
data needed to perform the installation.
"), p["device"]:"" );
}
Popup::Message( txt );
}
if( ret && (p["type"]:`unknown == `logical||
p["type"]:`unknown == `extended) )
{
integer num = p["type"]:`unknown == `extended ? 4 : p["nr"]:4;
list<map> pl = filter( map q, disk["partitions"]:[],
``( q["type"]:`unknown==`logical &&
q["nr"]:0 > num ));
y2milestone( "CanDelete pl:%1", pl );
integer pos = 0;
while( ret && pos<size(pl) )
{
ret = CanEdit( pl[pos]:$[], false );
if( ret )
pos = pos+1;
}
if( !ret && verbose )
{
if( p["mount"]:""=="swap" )
{
txt = sformat( _("
Device %1 cannot be removed because this would indirectly change
device %2 which contains activated swap that is needed to run
the installation.
"), p["device"]:"", pl[pos,"device"]:"" );
}
else
{
txt = sformat( _("
Device %1 cannot be removed because this would indirectly change
device %2 which contains data needed to perform the installation.
"), p["device"]:"", pl[pos,"device"]:"" );
}
Popup::Message( txt );
}
}
if (ret && substring(disk["device"]:"", 0, 9) == "/dev/dasd")
{
if (find(map partition, disk["partitions"]:[], {
return partition["device"]:"" != p["device"]:"" &&
!isempty(partition["used_by"]:[]); }) != nil)
{
txt = sformat(_("
Partition %1 cannot be removed since other partitions on the
disk %2 are in used."), p["device"]:"", disk["device"]:"");
Popup::Message(txt);
ret = false;
};
}
y2milestone( "CanDelete dev:%1 verbose:%2 ret:%3", p["device"]:"",
verbose, ret );
return( ret );
}
/**
* Reads and returns fstab from directory
*
* FIXME: please, add description of the list that is returned by this function.
*
* @struct [...unknown...]
*
* @param string directory
* @return list fstab?
*/
global list<map> ReadFstab(string dir)
{
list<map> ret = [];
list<any> vinfos = [];
boolean r = LibStorage::StorageInterface::readFstab( sint, dir, vinfos );
if( !r )
y2error( "ReadFstab sint dir %1 ret %2", dir, r );
else
{
foreach( any info, vinfos, {
map p = $[];
p = volumeMap( info, p );
ret = add( ret, p );
});
}
y2milestone( "ReadFstab from %1 ret %2", dir, ret );
return( ret );
}
global list<map> mountedPartitionsOnDisk( string disk )
{
map<string,any> d = GetDisk( GetTargetMap(), disk );
list<map> ret = filter( map p, d["partitions"]:[],
``(size(DeviceMounted(p["device"]:""))>0));
return( ret );
}
/**
* FIXME: please, add description of the list that is returned by this function.
*/
global list<map> GetCommitInfos()
{
list<any> infos = [];
LibStorage::StorageInterface::getCommitInfos(sint, infos);
list<map> ret = maplist(any info, infos, {
return $[ `destructive : LibStorage::CommitInfo::swig_destructive_get(info),
`text : LibStorage::CommitInfo::swig_text_get(info) ];
});
return ret;
}
string save_chtxt = "";
global string ChangeText()
{
list<string> texts = maplist(map info, GetCommitInfos(), {
string text = String::EscapeTags(info[`text]:"");
if (info[`destructive]:false)
text = "<font color=red>" + text + "</font>";
return text;
});
string ret = isempty(texts) ? "" : HTML::List(texts);
if (ret != save_chtxt)
{
LibStorage::StorageInterface::dumpCommitInfos(sint);
}
return ret;
}
global string LastAction()
{
string ret = LibStorage::StorageInterface::getLastAction( sint );
return( ret );
}
global string ExtendedErrorMsg()
{
string ret = LibStorage::StorageInterface::getExtendedErrorMessage( sint );
return( ret );
}
global void SetZeroNewPartitions( boolean val )
{
y2milestone( "SetZeroNewPartitions val:%1", val );
LibStorage::StorageInterface::setZeroNewPartitions( sint, val );
}
global void SetPartitionAlignment( symbol pal )
{
y2milestone( "SetPartitionAlignment val:%1", pal );
integer val = fromSymbol( conv_partalign, pal );
LibStorage::StorageInterface::setPartitionAlignment( sint, val );
}
global symbol GetPartitionAlignment()
{
integer val = LibStorage::StorageInterface::getPartitionAlignment( sint );
symbol pal = toSymbol( conv_partalign, val );
y2milestone( "GetPartitionAlignment val:%1", pal );
return( pal );
}
/**
* GetMountPoints()
* collect mountpoint:device as map to get a sorted list
*
* @returns: map of lists, the map key is the mount point,
* usually starting with a "/". Exception is "swap"
* For directory mount points (key starting with /) the value
* is a list [partitionName, fsid, targetdevice, raid_type]
* For swap mount points, the value is a list of lists:
* [[partitionName, fsid, targetdevice, raid_type], ...]
*
* FIXME: please, add more detailed description of the 'map of lists'
* with examples if possible.
*
* @struct $[ [...], [...], ... ]
*/
global define map GetMountPoints()
``{
map mountPoints = $[];
list swapPoints = [];
map<string,map> tg = GetTargetMap();
foreach ( string targetdevice, map target, tg,
``{
list<map> partitions = target["partitions"]:[];
foreach (map partition, partitions,
``{
string partitionName = partition["device"]:"";
string mountPoint = partition["mount"]:"";
integer fsid = partition["fsid"]:0;
if (mountPoint != "")
{
string raid_type = "";
if( partition["type"]:`undefined == `sw_raid )
{
raid_type = partition["raid_type"]:"";
}
// partition has a mount point
if (mountPoint == "swap")
{
swapPoints = add( swapPoints,
[partitionName, fsid, targetdevice, raid_type]);
}
else
{
mountPoints = add( mountPoints, mountPoint,
[partitionName, fsid, targetdevice, raid_type]);
}
}
});
});
if (size (swapPoints) > 0)
mountPoints = add (mountPoints, "swap", swapPoints);
if( !Stage::initial () )
{
list<map> cm = filter(map e, Partitions::CurMounted(),
``(search(e["spec"]:"","/dev/")==0));
foreach(map e, cm,
``{
if( !haskey( mountPoints, e["file"]:"" ) )
{
map p = GetPartition( tg, e["spec"]:"" );
if( size(p)>0 )
{
string raid_type = "";
if( p["type"]:`undefined == `sw_raid )
{
raid_type = p["raid_type"]:"";
}
map d = GetDiskPartition( e["spec"]:"" );
mountPoints[e["file"]:""] =
[ p["device"]:"", p["fsid"]:0, d["disk"]:"", raid_type ];
}
}
});
}
y2milestone( "ret %1", mountPoints );
return mountPoints;
}
/**
* Set <key> in partition <device> to the given <value> and return changed map <tg>
*
* @param map <string,map> tg
* @param string device name
* @string key
* @string value
* @return map <string,map> changed target map
*/
global define map<string,map> SetPartitionData( map<string,map> tg,
string device, string key,
any value )
``{
y2milestone( "SetPartitionData device=%1 key=%2 value=%3", device, key,
value );
map tmp = GetDiskPartitionTg( device, tg )[0]:$[];
string disk = tmp["disk"]:"";
string dev = GetDeviceName( tmp["disk"]:"", tmp["nr"]:(any)0 );
list r_part = filter(map part, tg[disk,"partitions"]:[],
``(part["device"]:"" != dev ));
if( size(r_part)!=size(tg[disk,"partitions"]:[]) )
{
map p = filter( map part, tg[disk,"partitions"]:[],
``(part["device"]:"" == dev ))[0]:$[];
if( size(p)>0 )
{
p[key] = value;
r_part = add( r_part, p );
tg[disk,"partitions"] = r_part;
}
}
return( tg );
}
/* remove <key> in partition <device> and return changed map <tg> */
global define map<string,map> DelPartitionData( map<string,map> tg,
string device, string key)
``{
y2debug( "device=%1, key=%2", device, key );
map tmp = GetDiskPartitionTg( device, tg )[0]:$[];
string disk = tmp["disk"]:"";
string dev = GetDeviceName( tmp["disk"]:"", tmp["nr"]:(any)0 );
list r_part = filter(map part, tg[disk,"partitions"]:[],
``(part["device"]:"" != dev ));
if( size(r_part)!=size(tg[disk,"partitions"]:[]) )
{
map p = filter( map part, tg[disk,"partitions"]:[],
``(part["device"]:"" == dev ))[0]:$[];
if( size(p)>0 )
{
p = filter(string k, any e, (map<string,any>)p, ``(k != key) );
r_part = add( r_part, p );
tg[disk,"partitions"] = r_part;
}
}
return( tg );
}
/**
* Check if a disk is a real disk and not RAID or LVM
*
* @param map entry (disk)
* @return boolean true if real disk
*
* @struct entry ~ $[
* "type":`CT_DISK,
* "driver" : "?",
* "readonly" : false / true,
* ]
*/
global define boolean IsRealDisk( map entry )
``{
return( entry["type"]:`CT_UNKNOWN==`CT_DISK &&
!(entry["type"]:`CT_UNKNOWN==`CT_DISK && entry["readonly"]:false &&
entry["driver"]:""=="vbd") );
}
/**
* Checks if a container is partitionable
*
* @param map entry
* @return boolean true if partitionable
*
* @struct entry ~ $[ "type" : ... ? ]
*/
global boolean IsPartitionable( map entry )
{
return entry["type"]:`CT_UNKNOWN==`CT_DMRAID || entry["type"]:`CT_UNKNOWN==`CT_DMMULTIPATH ||
entry["type"]:`CT_UNKNOWN==`CT_MDPART || IsRealDisk( entry );
}
global define boolean DeviceRealDisk( string device )
``{
boolean ret = false;
if( search( device, "LABEL" )!=0 && search( device, "UUID" )!=0 )
{
map dev = $[];
dev = GetDiskPartition( device );
ret = dev["disk"]:"" != "/dev/md" && dev["disk"]:"" != "/dev/loop" &&
search( dev["disk"]:"", "/dev/evms")!=0 &&
is( dev["nr"]:(any)0, integer );
if( !ret && dev["disk"]:"" != "/dev/md" )
{
map st = (map)SCR::Read( .target.stat, dev["disk"]:"" );
ret = !st["isdir"]:false;
}
}
y2milestone( "DeviceRealDisk %1 ret %2", device, ret );
return ret;
}
/***
* Determine if there is any Linux partition on this system.
*
* If there is none, we don't need to ask if the user wants to update or
* boot an installed system - he can only do a new installation anyway.
* No time-consuming or dangerous operations should be performed here,
* only simple checks for existence of a Linux (type 83) partition.
*
* @return boolean true if there is anything that might be a Linux partition
**/
global define boolean HaveLinuxPartitions() ``{
boolean ret = false;
foreach ( string dev, map disk, GetTargetMap(), ``{
if( !ret )
{
if( IsPartitionable( disk ) )
{
foreach( map e, disk["partitions"]:[], ``{
ret = ret ||
Partitions::IsLinuxPartition( e["fsid"]:Partitions::fsid_native );
});
}
}
});
y2milestone( "HaveLinuxPartitions ret=%1", ret );
return( ret );
};
/**
* Get list of all Linux Partitions on all real disks
* @return list Partition list
*/
global define list GetOtherLinuxPartitions()``{
list ret = [];
foreach ( string dev, map disk, GetTargetMap(), ``{
if( IsPartitionable( disk ) )
{
list<map> l = (list<map>) filter( map p, disk["partitions"]:[],
``(!p["format"]:false &&
Partitions::IsLinuxPartition(p["fsid"]:0)) );
l = filter(map p, l, ``(contains( [`xfs, `ext2, `ext3, `ext4, `btrfs, `jfs, `reiser],
p["used_fs"]:`unknown)));
l = filter(map p, l,
``(!FileSystems::IsSystemMp( p["mount"]:"", false )));
if( size(l)>0 )
{
ret = union( ret, l );
}
}
});
y2milestone( "GetOtherLinuxPartitions ret=%1", ret );
return( ret );
}
/**
* Check if swap paritition is availbe on a disk
* @param disk Disk to be checked
* @return boolean true if swap available.
*/
global boolean CheckSwapOn(string disk)
{
list<string> swaps = SwappingPartitions();
boolean ret = contains(SwappingPartitions(), disk);
y2milestone("CheckSwapOn disk:%1 ret:%2", disk, ret);
return ret;
}
/**
* Returns list of primary partitions found
*
* @param map <string,map> targets
* @param boolean foreign_os
* @return list of primary partitions
*/
list<map> GetPrimPartitions(map<string, map> targets, boolean foreign_os)
{
list<map> ret = [];
integer num_dos = 0;
integer num_win = 0;
integer num_os2 = 0;
integer num_linux = 0;
string linux_text = "Linux other";
string dos_text = "dos";
string win_text = "windows";
string os2_text = "OS/2 Boot Manager";
foreach(string disk, map data, targets,
``{
foreach(map part, data["partitions"]:[],
``{
string device = part["device"]:"";
if (part["type"]:`unknown == `primary && !part["create"]:false &&
SCR::Execute(.target.bash, "/usr/lib/YaST2/bin/check.boot " + device) == 0)
{
string text = "";
if( Partitions::IsDosWinNtPartition( part["fsid"]:0 ) &&
data["used_by_type"]:`UB_NONE==`UB_NONE )
{
map<symbol, any> resize_info = $[];
map<symbol, any> content_info = $[];
if (GetFreeInfo(device, false, resize_info, true, content_info, true) &&
content_info[`windows]:false)
{
if( contains( Partitions::fsid_dostypes, part["fsid"]:0 ) )
{
num_dos = num_dos+1;
text = dos_text;
}
else
{
num_win = num_win+1;
text = win_text;
}
}
}
else if( part["fsid"]:0 == 0x12 && !foreign_os )
{
text = "Vendor diagnostic";
}
else if( part["fsid"]:0 == 0x0a )
{
text = os2_text;
num_os2 = num_os2+1;
}
else if( part["fsid"]:0 == Partitions::fsid_native &&
size(part["mount"]:"")==0 && !foreign_os )
{
text = linux_text;
num_linux = num_linux+1;
}
if (!isempty(text))
{
map entry = $[ "device" : device, "string" : text ];
y2milestone( "new entry %1", entry );
ret = add(ret, entry);
}
}
});
});
y2milestone( "GetPrimPartitions foreign_os:%5 num_linux %1 num_win %2 num_dos %3 num_os2 %4",
num_linux, num_win, num_dos, num_os2, foreign_os );
integer num = 1;
if( num_linux>1 )
{
ret = maplist( map entry, ret,
``{
if( entry["string"]:""==linux_text )
{
entry["string"] = linux_text + sformat( " %1", num );
num = num+1;
}
return( entry );
});
}
num = 1;
if( num_dos>1 )
{
ret = maplist( map entry, ret,
``{
if( entry["string"]:""==dos_text )
{
entry["string"] = dos_text + sformat( " %1", num );
num = num+1;
}
return( entry );
});
}
num = 1;
if( num_win>1 )
{
ret = maplist( map entry, ret,
``{
if( entry["string"]:""==win_text )
{
entry["string"] = win_text + sformat( " %1", num );
num = num+1;
}
return( entry );
});
}
num = 1;
if( num_os2>1 )
{
ret = maplist( map entry, ret,
``{
if( entry["string"]:""==os2_text )
{
entry["string"] = os2_text + sformat( " %1", num );
num = num+1;
}
return( entry );
});
}
y2milestone( "GetPrimPartitions ret %1", ret );
return( ret );
}
global list<map> GetWinPrimPartitions(map<string, map> targets)
{
list<map> ret = GetPrimPartitions( targets, true );
y2milestone( "GetWinPrimPartitions ret %1", ret );
return( ret );
}
global list<string> GetUsedFs()
{
if (!InitLibstorage(false))
return nil;
list<string> r = LibStorage::StorageInterface::getAllUsedFs(sint);
y2milestone("GetUsedFs ret:%1", r);
return r;
}
global void SaveUsedFs()
{
y2milestone("SaveUsedFs");
SCR::Write(.sysconfig.storage.USED_FS_LIST, mergestring(GetUsedFs(), " "));
SCR::Write(.sysconfig.storage, nil);
}
global list<string> AddPackageList()
{
list<string> pl = hw_packages;
map<string, map> target_map = GetTargetMap();
boolean need_lvm = false;
boolean need_nfs = false;
boolean need_quota = false;
boolean need_crypt = false;
foreach (string k, map e, target_map, {
if (e["type"]:`CT_UNKNOWN == `CT_LVM)
need_lvm = true;
if (e["type"]:`CT_UNKNOWN == `CT_NFS)
need_nfs = true;
if (find(map part, e["partitions"]:[], { return FileSystems::HasQuota(part); }) != nil)
need_quota = true;
if (find(map part, e["partitions"]:[], { return part["enc_type"]:`none != `none; }) != nil)
need_crypt = true;
});
y2milestone("AddPackageList need_lvm:%1 need_nfs:%2 need_quota:%3 need_crypt:%4",
need_lvm, need_nfs, need_quota, need_crypt);
if (need_lvm)
{
pl = add(pl, "lvm2");
}
//nfs-client needs to be marked for installation if we have
//some NFS shares. It will pull in portmapper package(#436897)
if (need_nfs)
{
pl = add(pl, "nfs-client");
pl = add(pl, "yast2-nfs-client");
}
if( need_quota )
{
pl = add( pl, "quota" );
}
if( need_crypt )
{
pl = add( pl, "cryptsetup" );
pl = add( pl, "pam_mount" );
}
y2milestone("AddPackageList ret %1", pl);
return pl;
}
/**
* Takes care of selecting packages needed by storage
* in installation
* (replacement for HandlePackages in *_proposal clients)
*/
global void HandleProposalPackages()
{
//Use PackagesProposal to ensure that package selection
//does not get reset by this module (#433001)
import "PackagesProposal";
string proposal_ID = "storage_proposal";
list<string> pkgs = AddPackageList();
//Set rather than Add, there might be some packs left over
//from previous 'MakeProposal' we don't need now
//This also covers the case when AddPackagesList returns [] or nil
if (!PackagesProposal::SetResolvables(proposal_ID, `package, pkgs))
{
y2error("PackagesProposal::SetResolvables() for %1 failed", pkgs);
Report::Error(sformat(_("Add the following resolvables failed: %1"), pkgs));
}
if( Stage::initial() )
{
SaveUsedFs();
}
}
global list<string> GetForeignPrimary()
{
list<string> ret = [];
if( Arch::i386 () || Arch::ia64 () || Arch::x86_64 () )
{
foreach(map e, GetPrimPartitions( GetTargetMap(), false ), {
ret = add( ret, sformat( "%1 %2", e["device"]:"", e["string"]:"" ));
});
}
y2milestone( "ret=%1", ret );
return( ret );
}
/**
* Returns whether a partition is resizable
*
* @param map partition
* @return map resizable ?
*/
global define map IsResizable( map part )
``{
map ret = FileSystems::IsResizable(`unknown);
if ((!Arch::s390() && Partitions::IsResizable(part["fsid"]:0)) ||
part["type"]:`none == `lvm)
{
if( part["fsid"]:0==Partitions::fsid_swap )
{
ret = FileSystems::IsResizable(`swap);
}
else
{
ret = FileSystems::IsResizable(part["used_fs"]:`unknown);
}
}
y2milestone( "IsResizable part:%1 ret:%2", part, ret );
return( ret );
}
global boolean FreeCylindersAroundPartition(string device, integer& free_before, integer& free_after)
{
boolean ret = LibStorage::StorageInterface::freeCylindersAroundPartition(sint, device, free_before, free_after) == 0;
y2milestone("FreeCylindersAfterPartition ret:%1 free_before:%2 free_after:%3", ret, free_before, free_after);
return ret;
}
global string PathToDestdir(string p)
{
if (Installation::scr_destdir != "/")
p = Installation::scr_destdir + p;
return p;
}
define void HandleModulesOnBoot( map<string,map> targetMap )
``{
list<string> ml = filter( string e,
(list<string>) splitstring( Misc::SysconfigRead( .sysconfig.kernel.MODULES_LOADED_ON_BOOT, "" ), " \t"),
``(size(e)>0));
y2milestone( "HandleModulesOnBoot ml %1", ml );
boolean need_cryptoloop = false;
boolean need_fish2 = false;
foreach( string disk, map e, targetMap,
``{
foreach( map p, e["partitions"]:[],
``{
if( p["noauto"]:false && p["enc_type"]:`none!=`none )
{
if( p["enc_type"]:`none == `twofish )
need_cryptoloop = true;
else if( p["enc_type"]:`none == `twofish_old ||
p["enc_type"]:`none == `twofish_256_old )
need_fish2 = true;
}
});
});
y2milestone( "HandleModulesOnBoot need_fish2 %1 need_cryptoloop %2", need_fish2,
need_cryptoloop );
if( need_fish2 && find( string e, ml, ``(e=="loop_fish2"))==nil )
{
ml = add( ml, "loop_fish2" );
SCR::Write( .sysconfig.kernel.MODULES_LOADED_ON_BOOT,
mergestring( ml, " " ) );
}
if( need_cryptoloop && find( string e, ml, ``(e=="cryptoloop"))==nil )
{
ml = add( ml, "cryptoloop" );
SCR::Write( .sysconfig.kernel.MODULES_LOADED_ON_BOOT,
mergestring( ml, " " ) );
}
if( need_cryptoloop && find( string e, ml, ``(e=="twofish"))==nil )
{
ml = add( ml, "twofish" );
SCR::Write( .sysconfig.kernel.MODULES_LOADED_ON_BOOT,
mergestring( ml, " " ) );
}
}
/**
* Adds an entry into the fstab
*
* @param map entry
* @return integer (0 and higher == OK, otherwise error)
*/
integer AddFstabEntry( map e )
{
y2milestone( "AddFstabEntry entry:%1", e );
integer ret = 0;
integer freq = e["freq"]:0;
integer passno = e["passno"]:0;
string dev = e["spec"]:"";
string m = e["mount"]:"";
string vfs = e["vfstype"]:"auto";
string opts = e["mntops"]:"defaults";
ret = LibStorage::StorageInterface::addFstabEntry( sint, dev, m, vfs, opts,
freq, passno );
if( ret<0 )
y2error( "ret:%1 entry:%2", ret, e );
return( ret );
}
global void ActivateHld(boolean val)
{
y2milestone("ActivateHld val:%1", val);
LibStorage::StorageInterface::activateHld(sint, val);
}
global void ActivateMultipath(boolean val)
{
y2milestone("ActivateMultipath val:%1", val);
LibStorage::StorageInterface::activateMultipath(sint, val);
}
/**
* Writes fstab to the disk
*/
global define void WriteFstab()
``{
y2milestone( "WriteFstab called" );
Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "proc" ) );
Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "sys" ) );
Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "debug" ) );
if( Hotplug::haveUSB )
Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "usb" ) );
Storage::AddFstabEntry( FileSystems::GetFstabDefaultMap( "pts" ) );
map m = $[];
integer num = 0;
foreach( string tdevice, any tdata, StorageDevices::ZipDrives(),
``{
m = FileSystems::GetFstabDefaultMap( "zip" );
string zfile = "/zip";
if( num > 0 )
zfile = zfile + sformat( "%1", num );
m["mount"] = "/media"+zfile;
m["spec"] = tdevice+"4";
Storage::AddFstabEntry( m );
num = num+1;
});
HandleModulesOnBoot( GetTargetMap() );
}
global define map<string,map> SpecialBootHandling( map<string,map> tg )
``{
boolean have_ppc_boot = false;
foreach( string dev, map disk, tg,
``{
foreach(map part, disk["partitions"]:[],
``{
if( !have_ppc_boot &&
part["fsid"]:0 == Partitions::fsid_prep_chrp_boot &&
size(part["mount"]:"")==0 && part["create"]:false )
{
have_ppc_boot = true;
}
});
});
y2milestone( "SpecialBootHandling: have_ppc_boot:%1", have_ppc_boot );
foreach( string dev, map disk, tg,
``{
list new_part = [];
foreach(map part, disk["partitions"]:[],
``{
// convert a mount point of /boot to a 41 PReP boot partition
if( Partitions::PrepBoot() &&
part["mount"]:"" == Partitions::BootMount() && !have_ppc_boot )
{
integer id = Partitions::fsid_prep_chrp_boot;
part["format"] = false;
part["mount"] = "";
part["fstype"] = Partitions::FsIdToString( id );
part["prep_install"] = true;
if( !part["create"]:false && part["fsid"]:0 != id )
{
part["ori_fsid"] = part["fsid"]:0;
part["change_fsid"] = true;
}
part["fsid"] = id;
y2milestone( "SpecialBootHandling modified Prep part=%1", part );
}
if( Arch::board_mac () &&
part["mount"]:"" == Partitions::BootMount() )
{
integer id = Partitions::fsid_mac_hfs;
part["mount"] = "";
part["fstype"] = Partitions::FsIdToString( id );
part["fsid"] = id;
part["used_fs"] = `hfs;
part["detected_fs"] = `hfs;
y2milestone( "SpecialBootHandling modified hfs part=%1", part );
}
if( Arch::ia64 () &&
part["mount"]:"" == Partitions::BootMount() )
{
integer id = Partitions::fsid_gpt_boot;
part["fsid"] = id;
part["fstype"] = Partitions::FsIdToString( id );
if( !part["create"]:false && part["detected_fs"]:`none==`vfat )
{
part["format"] = false;
}
y2milestone( "SpecialBootHandling modified GPT boot part=%1", part );
}
new_part = add( new_part, part );
});
tg[dev,"partitions"] = new_part;
});
return( tg );
}
global define boolean PerformLosetup( map& loop, boolean format )
``{
boolean crypt_ok = false;
string pwd = loop["passwd"]:"";
string device = loop["partitionName"]:"";
string mdir = Storage::SaveDumpPath("tmp_mp" );
y2milestone( "PerformLosetup mdir:%1", mdir );
if( (integer)SCR::Read(.target.size, mdir ) >= 0 )
{
SCR::Execute(.target.bash, "rm -f " + mdir );
}
SCR::Execute(.target.mkdir, mdir );
crypt_ok = Storage::SetCryptPwd( device, pwd ) &&
Storage::SetCrypt( device, true, false ) &&
Storage::Mount( device, mdir );
if( crypt_ok )
{
any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
integer ret = LibStorage::StorageInterface::getVolume( sint, device,
vinfo );
if( ret!=0 )
{
y2error( "PerformLosetup device:%1 not found (ret:%2)", device, ret );
crypt_ok = false;
}
else
{
loop["loop_dev"] = "/dev/mapper/cr_" +
substring( device, findlastof( device, "/" )+1 );
y2milestone( "PerformLosetup crdev:%1", loop["loop_dev"]:"" );
}
SCR::Execute(.target.bash, "umount " + mdir );
}
y2milestone( "PerformLosetup ret %1", crypt_ok );
return( crypt_ok );
}
/**
* Detects a filesystem on a device
*
* @param device name
* @return symbol filesystem
*/
global define symbol DetectFs( string device )
``{
symbol ret = `unknown;
y2milestone( "DetectFs:%1", device );
any vinfo = LibStorage::VolumeInfo::new("LibStorage::VolumeInfo");
integer r = LibStorage::StorageInterface::getVolume( sint, device, vinfo );
if( r!=0 )
{
y2error( "DetectFs device:%1 not found (ret:%2)", device, r );
}
else
{
map curr = $[];
curr = volumeMap( vinfo, curr );
ret = curr["detected_fs"]:`unknown;
}
y2milestone( "DetectFs ret %1", ret );
return( ret );
}
global define map GetBootPartition( string disk )
``{
map ret = $[];
map tg = GetTargetMap();
ret = filter( map p, tg[disk,"partitions"]:[], ``(p["boot"]:false))[0]:$[];
y2milestone( "disk:%1 ret:%2", disk, ret );
return( ret );
}
global string HdToIseries( string input )
``{
string ret = input;
string regex = "/dev/hd[a-z][0-9]*";
if( regexpmatch( input, regex ))
{
ret = "/dev/iseries/vd" + substring( ret, 7 );
}
y2milestone( "HdToIseries input:%1 ret:%2", input, ret );
return( ret );
}
global string SLES9PersistentDevNames( string input )
``{
string ret = input;
string regex1 = "/dev/disk/by-id/.*";
string regex2 = "/dev/disk/by-path/.*";
string prefix = "scsi-";
string tmpdev = "";
if( regexpmatch( input, ".*-part[0-9]*$" ))
{
return input;
}
if( regexpmatch( input, ".*/by-id/(scsi|ccw|usb|ata)-.*$" ))
{
return input;
}
if( regexpmatch( input, regex1 ))
{
if (regexpmatch ( input, ".*/by-id/0X.{4}p?[0-9]?$" ) )
{
prefix = "ccw-";
}
tmpdev = "/dev/disk/by-id/" + prefix +
substring( input, findlastof(input, "/")+1 );
y2milestone( "by id tmp %1", tmpdev );
ret = tmpdev;
}
else if( regexpmatch( input, regex2 ))
{
tmpdev = input;
y2milestone( "by path tmp %1", tmpdev );
}
if( size(tmpdev)>0 )
{
if( regexpmatch( tmpdev, ".*p[0-9]*$" ) )
{
ret = regexpsub( tmpdev, "(.*)p([0-9]*)$", "\\1-part\\2" );
}
else
{
ret = regexpsub( tmpdev, "(.*[[:alpha:][:punct:]])([0-9]*)$", "\\1-part\\2" );
}
}
y2milestone( "SLES9PersistentDevNames input:%1 ret:%2", input, ret );
return( ret );
}
global string HdDiskMap( string input, map diskmap )
``{
string ret = input;
if (IsKernelDeviceName(input))
{
map d = GetDiskPartition( input );
if( haskey( diskmap, d["disk"]:"" ))
{
ret = GetDeviceName( diskmap[d["disk"]:""]:"", d["nr"]:(any)0 );
}
}
y2milestone( "HdDiskMap input:%1 ret:%2", input, ret );
return( ret );
}
global define map BuildDiskmap( map oldv )
``{
map d = (map)SCR::Read( .target.stat,
Installation::destdir + "/var/lib/hardware" );
y2milestone( "BuildDiskmap oldv:%1 Vers:%2", oldv, DiskMapVersion );
y2milestone( "dir:%1 d:%2", Installation::destdir+"/var/lib/hardware", d );
if( d["isdir"]:false && (oldv != DiskMapVersion || size(oldv)==0) )
{
DiskMap = $[];
string cmd = "";
cmd = "LIBHD_HDDB_DIR=" + Installation::destdir + "/var/lib/hardware " +
"hwinfo --verbose --map";
y2milestone( "BuildDiskmap cmd %1", cmd );
map bo = (map)SCR::Execute (.target.bash_output, cmd );
y2milestone( "BuildDiskmap bo %1", bo );
if( bo["exit"]:1==0 && size(bo["stdout"]:"")>0 )
{
list<string> lines = splitstring( bo["stdout"]:"", "\n" );
foreach( string line, lines,
``{
list<string> disks = filter( string d,
splitstring( line, " \t" ),
``(size(d)>0));
if( size(disks)>1 )
{
integer index = 1;
while( index<size(disks) )
{
DiskMap[disks[index]:""] = disks[0]:"";
index = index+1;
}
}
});
}
if( bo["exit"]:1==0 )
DiskMapVersion = oldv;
else
DiskMapVersion = $[];
}
y2milestone( "BuildDiskmap DiskMap %1", DiskMap );
y2milestone( "BuildDiskmap DiskMapVersion %1", DiskMapVersion );
return( DiskMap );
}
global define list<string> GetTranslatedDevices( map oldv, map newv,
list<string> names )
{
y2milestone( "GetTranslatedDevices old:%1 new:%2", oldv, newv );
y2milestone( "GetTranslatedDevices names %1", names );
list<string> ret = names;
map dm = BuildDiskmap( oldv );
if( size(dm)>0 )
{
ret = maplist( string n, ret, ``(HdDiskMap( n, dm )));
}
if( (oldv["major"]:0<9 || (oldv["major"]:0==9 && oldv["minor"]:0==0)) &&
Arch::board_iseries () )
{
ret = maplist( string n, ret, ``(HdToIseries( n )));
}
if( oldv["major"]:0==9 )
{
ret = maplist( string n, ret, ``(SLES9PersistentDevNames( n )));
}
// convert EVMS names to LVM
// FIXME: add version checking, but does not seem necessary, since non-LVM
// installations will not be affected by this conversion at all
ret = maplist (string n, ret, {
if (substring (n, 0, 15) == "/dev/evms/lvm2/")
n = "/dev/" + substring (n, 15);
return n;
});
y2milestone( "GetTranslatedDevices ret %1", ret );
return( ret );
}
void CallInsserv( boolean on, string name )
{
y2milestone( "CallInsserv on:%1 name:%2", on, name );
string scrname = "/etc/init.d/" + name;
if( SCR::Read( .target.size, scrname )>0 )
{
string cmd = "cd / && /sbin/insserv ";
if( !on )
cmd = cmd + "-r ";
cmd = cmd + scrname;
y2milestone( "CallInsserv cmd %1", cmd );
map bo = (map)SCR::Execute (.target.bash_output, cmd );
y2milestone( "CallInsserv bo %1", bo );
}
}
global void FinishInstall()
{
y2milestone("FinishInstall initial:%1", Stage::initial());
map<string, map> target_map = GetTargetMap();
if( Stage::initial() )
{
HandleModulesOnBoot(target_map);
}
boolean need_crypt = false;
boolean need_md = false;
boolean need_lvm = false;
boolean need_dmraid = false;
boolean need_dmmultipath = false;
foreach (string k, map e, target_map, {
if (find(map part, e["partitions"]:[], { return part["enc_type"]:`none != `none; }) != nil)
need_crypt = true;
if (e["type"]:`CT_UNKNOWN == `CT_MD && !isempty(e["partitions"]:[]))
need_md = true;
if( e["type"]:`CT_UNKNOWN==`CT_MDPART )
need_md = true;
if( e["type"]:`CT_UNKNOWN==`CT_LVM )
need_lvm = true;
if( e["type"]:`CT_UNKNOWN==`CT_DMRAID )
need_dmraid = true;
if( e["type"]:`CT_UNKNOWN==`CT_DMMULTIPATH )
need_dmmultipath = true;
});
y2milestone( "FinishInstall need crypto:%1 md:%2 lvm:%3 dmraid:%4 dmmultipath:%5",
need_crypt, need_md, need_lvm, need_dmraid, need_dmmultipath );
if( need_crypt )
{
CallInsserv( true, "boot.crypto" );
CallInsserv( true, "boot.crypto-early" );
}
CallInsserv( need_md, "boot.md" );
CallInsserv( need_lvm, "boot.lvm" );
CallInsserv( need_dmraid, "boot.dmraid" );
CallInsserv( need_dmmultipath, "boot.multipath" );
CallInsserv( need_dmmultipath, "multipathd" );
y2milestone("FinishInstall done");
}
global map GetEntryForMountpoint(string mp)
{
list<map> partitions = [];
foreach(string dev, map disk, GetTargetMap(), {
list<map> tmp = filter(map part, disk["partitions"]:[], { return part["mount"]:"" == mp; });
partitions = (list<map>) union(partitions, tmp);
});
return partitions[0]:$[];
}
global define list GetRootInitrdModules()
``{
map partition = GetEntryForMountpoint( "/" );
y2milestone("GetRootInitrdModules root partition %1", partition );
map<string,map> tg = GetTargetMap();
map disk = $[];
foreach( string k, map d, tg,
``{
if( size(disk)==0 &&
find( map p, d["partitions"]:[],
``(!p["delete"]:false &&
p["device"]:""==partition["device"]:""))!=nil )
disk = d;
});
y2milestone( "GetRootInitrdModules disk %1",
haskey(disk,"partitions")?remove(disk,"partitions"):disk );
list initrdmodules =
FileSystems::GetNeededModules( partition["used_fs"]:`ext2 );
if( partition["type"]:`unknown == `sw_raid )
{
string t = partition["raid_type"]:"";
if (!contains (initrdmodules, t))
{
initrdmodules = add (initrdmodules, t);
}
}
if( partition["type"]:`unknown == `lvm )
{
string vgdevice = substring( partition["device"]:"", 5 );
vgdevice = "/dev/" + substring( vgdevice, 0, findfirstof( vgdevice, "/" ));
list<string> mod =
(list<string>) maplist(map k, filter(map e, tg["/dev/md","partitions"]:[],
``(e["used_by_device"]:""==vgdevice) ),
``(k["raid_type"]:""));
y2milestone( "GetRootInitrdModules mod %1", mod );
foreach(string e, mod,
``{
if( size(e)>0 && !contains( initrdmodules, e ) )
{
initrdmodules = add( initrdmodules, e );
}
});
if( !contains( initrdmodules, "dm_mod" ) )
{
initrdmodules = add( initrdmodules, "dm_mod" );
}
}
if( size(disk["modules"]:[])>0 )
{
y2milestone( "adding disk modules %1", disk["modules"]:[] );
foreach( string m, disk["modules"]:[],
``{
if( !contains( initrdmodules, m ))
{
initrdmodules = add( initrdmodules, m );
}
});
}
if( size(disk["driver_module"]:"")>0 )
{
string m = disk["driver_module"]:"";
y2milestone( "adding driver modules %1", m );
if( !contains( initrdmodules, m ))
{
initrdmodules = add( initrdmodules, m );
}
}
SCR::UnmountAgent (.proc.modules);
map lmod = (map) SCR::Read(.proc.modules);
y2milestone( "GetRootInitrdModules lmod:%1", lmod );
if( size(lmod["edd"]:$[])>0 )
initrdmodules = add( initrdmodules, "edd" );
y2milestone( "GetRootInitrdModules ret %1", initrdmodules );
return initrdmodules;
};
global boolean CheckForLvmRootFs()
{
map part = GetEntryForMountpoint("/");
boolean ret = part["type"]:`primary == `lvm;
y2milestone("CheckForLvmRootFs root:%1 ret:%2", part, ret);
return ret;
}
global boolean CheckForMdRootFs()
{
map part = GetEntryForMountpoint("/");
boolean ret = part["type"]:`primary == `sw_raid;
y2milestone("CheckForMdRootFs root:%1 ret:%2", part, ret);
return ret;
}
global define integer NumLoopDevices()
{
map bo = (map)WFM::Execute (.local.bash_output, "losetup -a" );
list<string> sl = splitstring( bo["stdout"]:"", "\n" );
sl = filter( string s, sl, ``(search( s, "/dev/loop" )==0 ));
sl = maplist( string s, sl, ``(substring( s, 0, search( s, ":" ))));
sl = maplist( string s, sl, ``(substring( s, 9 )));
list<integer> il = sort( maplist( string s, sl, ``(tointeger(s))));
integer ret = il[size(sl)-1]:-1 + 1;
y2milestone( "NumLoopDevices ret:%1", ret );
return( ret );
}
//-----------------------------------------------------
// convert partitions to fstab entries
// return map (might be empty)
global define map onepartition2fstab (map part, integer& other_nr)
``{
y2milestone( "onepartition2fstab part=%1", part );
if (part["delete"]:false ||
part["type"]:`unknown == `extended ||
(contains( [ `lvm, `sw_raid, `evms ], part["type"]:`unknown ) &&
size(part["mount"]:"")==0) ||
(part["enc_type"]:`none!=`none && !part["noauto"]:false) ||
part["used_by_type"]:`UB_NONE != `UB_NONE ||
(contains( [ Partitions::fsid_prep_chrp_boot, Partitions::fsid_lvm,
Partitions::fsid_raid ], part["fsid"]:0 ) &&
size(part["mount"]:"")==0))
{
return $[];
}
string spec = part["device"]:"";
if( part["mountby"]:`device == `label && size(part["label"]:"")>0 )
{
spec = sformat("LABEL=%1", part["label"]:"" );
}
else if( part["mountby"]:`device == `uuid && size(part["uuid"]:"")>0 )
{
spec = sformat("UUID=%1", part["uuid"]:"" );
}
y2debug( "onepartition2fstab spec=%1", spec );
string mount_point = part["mount"]:"";
integer fsid = part["fsid"]:0;
symbol used_fs = part["used_fs"]:`ext2;
boolean format = part["format"]:false;
string vfstype = "unknown"; // keep "unknown", used again below
integer freq = 0;
integer passno = 0;
string mntops = part["fstopt"]:"";
if( mount_point == "swap" )
{
vfstype = "swap";
if (isempty(mntops))
{
mntops = FileSystems::GetFstabDefaultMap("swap")["mntops"]:"";
}
passno = 0;
}
else if( fsid==Partitions::fsid_native || fsid==Partitions::fsid_lvm ||
(part["type"]:`unknown == `evms &&
part["detected_fs"]:`none!=`unknown) )
{
vfstype = FileSystems::GetMountString( used_fs,
(format ? "ext2" : "auto"));
freq = 1;
if( mount_point == "/" )
{
passno = 1;
}
else if( mount_point != "" )
{
passno = 2;
}
else if( Stage::initial () && !Arch::s390 () )
{
mount_point = "/data" + other_nr;
// Don't mount and fsck this filesystem during boot, its
// state is unknown.
mntops = "noauto,user";
vfstype = "auto";
freq = 0;
passno = 0;
other_nr = other_nr + 1;
y2milestone( "TT add MountPoint %1", mount_point );
}
}
else if( (Arch::i386()||Arch::ia64()||Arch::x86_64()) &&
size(mount_point)>0 &&
(used_fs==`vfat || used_fs==`ntfs) &&
(contains(union(union(Partitions::fsid_dostypes,
Partitions::fsid_ntfstypes),
Partitions::fsid_wintypes), fsid ) ||
fsid==Partitions::fsid_gpt_boot))
{
freq = 0;
passno = 0;
string lower_point = tolower( mount_point );
if( lower_point != "" && mount_point != lower_point)
{
lower_point = PathToDestdir(lower_point);
y2milestone( "symlink %1 -> %2",
substring(mount_point,(findlastof(mount_point,"/")+1)),
lower_point );
SCR::Execute(.target.symlink,
substring(mount_point,(findlastof(mount_point,"/")+1)),
lower_point);
}
vfstype = FileSystems::GetMountString( used_fs, "auto" );
}
else if( (Arch::sparc () || Arch::alpha ()) &&
contains (Partitions::fsid_skipped, fsid))
{
return $[]; // skip "whole disk" partition
}
else
{
return $[]; // unknown type
}
if( part["detected_fs"]:`unknown == `unknown || part["noauto"]:false )
{
passno = 0;
}
map ret = $[ "spec":spec,
"mount":mount_point,
"vfstype":vfstype,
"mntops":mntops,
"freq":freq,
"device":part["device"]:"",
"passno":passno ];
if( size(ret["mntops"]:"")==0 )
{
ret["mntops"] = "defaults";
}
y2milestone( "onepartition2fstab ret=%1", ret );
return( ret );
};
global void AddHwPackage( string name )
{
y2milestone( "AddHwPackage name %1 list:%2", name, hw_packages );
if( find( string s, hw_packages, ``(s==name)) == nil )
hw_packages = add( hw_packages, name );
y2milestone( "AddHwPackage list:%1", hw_packages );
}
global void SwitchUiAutomounter(boolean on)
{
y2milestone("SwitchUiAutomounter on:%1", on);
if (!on)
{
SCR::Execute(.dbus.system.method,
$[ `destination : "org.freedesktop.Hal",
`path : "/org/freedesktop/Hal/Manager",
`interface : "org.freedesktop.Hal.Manager",
`method : "AcquireGlobalInterfaceLock" ],
[ "org.freedesktop.Hal.Device.Storage",
true ]);
}
else
{
SCR::Execute(.dbus.system.method,
$[ `destination : "org.freedesktop.Hal",
`path : "/org/freedesktop/Hal/Manager",
`interface : "org.freedesktop.Hal.Manager",
`method : "ReleaseGlobalInterfaceLock" ],
[ "org.freedesktop.Hal.Device.Storage" ]);
}
y2milestone("SwitchUiAutomounter exit");
}
global void DumpObjectList()
{
if (!InitLibstorage(false))
return;
LibStorage::StorageInterface::dumpObjectList(sint);
}
global void SetDefaultMountBy(symbol mby)
{
integer val = fromSymbol( conv_mountby, mby );
LibStorage::StorageInterface::setDefaultMountBy(sint, val);
}
global symbol GetDefaultMountBy()
{
integer val = LibStorage::StorageInterface::getDefaultMountBy(sint);
symbol ret = toSymbol(conv_mountby, val);
return ret;
}
global symbol GetMountBy( string device )
{
integer val = 0;
integer r = LibStorage::StorageInterface::getMountBy( sint, device, val );
symbol ret = toSymbol( conv_mountby, val );
return( ret );
}
global boolean SaveDeviceGraph(string filename)
{
boolean ret = LibStorage::saveDeviceGraph(sint, filename);
y2milestone("SaveDeviceGraph filename:%1 ret:%2", filename, ret);
return ret;
}
global boolean SaveMountGraph(string filename)
{
boolean ret = LibStorage::saveMountGraph(sint, filename);
y2milestone("SaveMountGraph filename:%1 ret:%2", filename, ret);
return ret;
}
global boolean DeviceMatchFstab( string device, string fstab_spec )
{
boolean ret = false;
map<string,map> tg = GetTargetMap();
string ts = fstab_spec;
if (IsKernelDeviceName(fstab_spec))
{
// translate fstab_spec from old to new kernel device name
ts = GetTranslatedDevices( $[], $[], [ fstab_spec ] )[0]:"";
if( ts!=fstab_spec )
y2milestone( "DeviceMatchFstab translate %1 --> %2", fstab_spec, ts );
}
list<map> pl = GetPartitionLst( tg, ts );
ret = find( map p, pl, ``(p["device"]:"" == device) )!=nil;
y2milestone( "DeviceMatchFstab device:%1 fstab:%2 ret:%3", device,
fstab_spec, ret );
return( ret );
}
global boolean IsPersistent( map p )
{
boolean ret = contains( [ `lvm, `sw_raid, `dm ], p["type"]:`unknown );
if( !ret && contains( [ `primary, `logical, `extended ], p["type"]:`unknown ))
{
map d = GetDisk( GetTargetMap(), p["device"]:"" );
ret = d["type"]:`CT_UNKNONW==`CT_DMRAID || d["type"]:`CT_UNKNONW==`CT_DMMULTIPATH ||
size(d["udev_id"]:[])>0;
}
y2milestone("IsPersistent device:%1 ret:%2", p["device"]:"", ret);
return ret;
}
}
ACC SHELL 2018