home *** CD-ROM | disk | FTP | other *** search
Text File | 2006-11-29 | 31.7 KB | 1,179 lines |
- /**
- * File:
- * raid_ui.ycp
- *
- * Module:
- * Configuration of raid
- *
- * Summary:
- * User interface functions.
- *
- * Authors:
- * Michael Hager <mike@suse.de>
- *
- * $Id: raid_ui.ycp 33346 2006-10-12 10:47:02Z fehr $
- *
- * All user interface functions for RAID.
- *
- */
-
- {
-
- textdomain "storage";
-
-
- import "Wizard";
- import "Storage";
- import "FileSystems";
- import "Partitions";
- import "Label";
- import "Popup";
-
- include "partitioning/raid_lib.ycp";
- include "partitioning/partition_defines.ycp";
- include "partitioning/custom_part_lib.ycp";
-
- /**
- * AbortDialog
- **/
- define symbol AbortDialog()
- ``{
- if( Popup::ReallyAbort(true))
- return `yes;
- else
- return `back;
- }
-
-
- define boolean CheckRaidNumbers( integer raidnr )
- ``{
- integer max_raid = 27;
- list<map> parts = get_possible_rds( Storage::GetTargetMap() );
- string dev = sformat("md%1", raidnr);
- parts = filter( map e, parts, ``(e["used_by"]:""==dev));
- y2milestone( "CheckRaidNumbers size %1 parts %2", size(parts), parts );
- if( size(parts) >= max_raid )
- {
- // popup text
- string text = sformat(_("
- The maximum number of partitions in a software raid is %1.
- You want to add more partitions to the raid than can be
- handled by the current version of software raid.
- "), max_raid);
- Popup::Error(text);
- }
- return( size(parts) < max_raid );
- }
-
-
- /**
- * Help for RaidTypeDialog
- * @return string
- */
- define string ChooseRaidTypeHelp()
- ``{
- // help text
- string help = _("<p><b>RAID 0:</b> This level increases your disk performance.
- There is <b>NO</b> redundancy in this mode. If one of the drives crashes, data recovery will not be possible.</p>
- ");
-
- // help text
- help = help + _("<p><b>RAID 1:</b> <br>This mode has the best redundancy. It can be
- used with two or more disks. This mode maintains an exact copy of all data on all
- disks. As long as at least one disk is still working, no data is lost. The partitions
- used for this type of RAID should have approximately the same size.</p>
- ");
-
- // help text
- help = help + _("<p><b>RAID 5:</b> <br>This mode combines management of a larger number
- of disks and still maintains some redundancy. This mode can be used on three disks or more.
- If one disk fails, all data is still intact. If two disks fail simultaneously, all data is lost</p>
- ");
-
- // help text
- help = help + _("<p><b>Multipath:</b> <br>This mode allow access to the same physical device
- over multiple controllers for redundancy against a fault in a controller card. This mode can be used with at least two devices<p>
- ");
-
- return help;
- };
-
-
- /**
- * Contents for dialog ChooseRaidType
- * @return term
- **/
- define term get_choose_raid_type_contents( string raid, symbol what )
- ``{
- integer space = 0;
- term MpDetect = `Empty();
-
- if( what == `settings )
- {
- space = 5;
- }
- else
- {
- MpDetect = `Left( `HBox( `HSpacing(7),
- `PushButton(`id(`mp_auto),
- // button text
- _("Auto&detect Multipath"))));
- }
-
- // Translators, 'Striping' is a technical term here. Translate only if
- // you are sure!! If in doubt, leave it in English.
- string str_text = _("RAID &0 (Striping)");
- // Translators, 'Mirroring' is a technical term here. Translate only if
- // you are sure!! If in doubt, leave it in English.
- string mir_text = _("RAID &1 (Mirroring)");
- // Translators, 'Redundant Striping' is a technical term here. Translate
- // only if you are sure!! If in doubt, leave it in English.
- string r5_text = _("RAID &5 (Redundant Striping)");
- // label text
- string mp_text = _("&Multipath (Redundant access over two controllers)");
-
-
-
-
- return
- `VBox(
- `VSpacing(space),
- // popup text
- `Heading (_("What type of RAID would you like to create?")),
- `VSpacing(1),
- `RadioButtonGroup(
- `id("raid_type"),
- `HSquash(
- `VBox(
- `Left(`RadioButton(`id("raid0"), str_text,
- raid=="raid0")),
- `VSpacing (1),
- `Left(`RadioButton(`id("raid1"), mir_text,
- raid=="raid1")),
- `VSpacing (1),
- `Left(`RadioButton(`id("raid5"), r5_text,
- raid=="raid5"))
- /*
- `VSpacing (1),
- `Left(`RadioButton(`id("multipath"), mp_text,
- raid=="multipath")),
- MpDetect
- */
- )
- )
- ),
- `VSpacing(space)
- );
-
-
- };
-
- define string RaidMultipathAutoHelp()
- ``{
- // help text
- string help = _("<p>The list contains the devices that could be automatically
- detected for multipath setup. Disable the devices not to
- have activated by double-clicking the table line and continue when
- finished. If you go back, none of the autodetected multipath raid devices
- are created.</p>
- <p>If you deselect lines, the names of the raid devices
- after the deselected lines will be changed.</p>
- ");
- return( help );
- };
-
-
- /**
- * RaidMultipathAuto Dialog
- * @return symbol
- */
- define symbol RaidMultipathAuto()
- ``{
- // Choose Raid Type ...
- /////////////////////////////////////////////////////////////////
- y2milestone( "enter" );
-
- // heading text
- string caption = _("RAID Wizard: Multipath Autodetection");
- map<string,map> tg = Storage::GetTargetMap();
- list<map> raids = tg["/dev/md","partitions"]:[];
- list<map> mp_raids = filter( map p, raids,
- ``(p["create"]:false &&
- p["raid_type"]:""=="multipath"));
- foreach( map p, mp_raids,
- ``{
- foreach( string dev, map disk, tg,
- ``{
- list new_part = [];
- foreach( map pt, disk["partitions"]:[],
- ``{
- if( pt["used_by"]:""==substring(p["device"]:"",5) )
- {
- pt = filter( string k, any value, (map<string,any>)pt,
- ``( k != "used_by" && k != "used_by_type" ));
- if( pt["change_fsid"]:false )
- {
- pt["fsid"] = pt["ori_fsid"]:0;
- pt["fstype"] = pt["ori_fstype"]:"";
- pt = filter( string key, any value, (map<string,any>)pt,
- ``( key != "ori_fsid" &&
- key != "change_fsid" &&
- key != "ori_fstype" ));
- }
- }
- new_part = add( new_part, pt );
- });
- tg[dev,"partitions"] = new_part;
- });
- raids = filter( map part, raids, ``(part["nr"]:0 != p["nr"]:0));
- });
- if( haskey( tg, "/dev/md" ))
- {
- tg["/dev/md","partitions"] = raids;
- }
- map<integer,list<string> > at = $[];
- list raid_list = [];
- list raid_enab = [];
- integer raid_num = -1;
- integer i=0;
- foreach(list<string> entry, Storage::AutodetectMultipathRaid( tg ),
- ``{
- raid_num = get_free_raid_nr( tg, raid_num+1 );
- raid_list = add( raid_list, raid_num );
- raid_enab = add( raid_enab, true );
- string dev = Storage::GetDeviceName( "/dev/md", raid_num );
- at[i] = entry;
- i = i+1;
- });
- y2milestone( "at=%1", at );
- y2milestone( "rl=%1", raid_list );
- term contents =
- // popup text
- `Label(_("No automatically configurable\nmultipath devices detected"));
- if( size(at)>0 )
- {
- integer i = 0;
- list ct = maplist( integer key, list content, at,
- ``{
- term a = `item( `id(i) );
- // label text
- a = add( a, _("Yes") );
- a = add( a, Storage::GetDeviceName( "/dev/md",
- raid_list[key]:255 ));
- a = add( a, content[0]:"" );
- a = add( a, content[1]:"" );
- string rest = "";
- if( size(content)>2 )
- {
- rest = mergestring( (list<string>)remove(remove(content,0),0),
- " ");
- }
- a = add( a, rest );
- i = i + 1;
- return( a );
- });
- term header = `header();
- // heading text
- header = add( header, _("Create") );
- // heading text
- header = add( header, _("Raid Device") );
- // heading text
- header = add( header, _("Partition 1") );
- // heading text
- header = add( header, _("Partition 2") );
- // heading text
- header = add( header, _("Other...") );
- contents = `HBox(`HSpacing(8),
- `VBox(`VSpacing(2),
- `Table( `id(`mp_table), `opt(`notify),
- header, ct ),
- `VSpacing(2) ),
- `HSpacing(8));
- }
-
- Wizard::SetContentsButtons(caption, contents, RaidMultipathAutoHelp(),
- Label::BackButton(), Label::NextButton());
-
- symbol ret = `next;
-
- do
- {
- ret = (symbol)UI::UserInput();
- y2milestone( "ret %1", ret );
-
- if( ret == `mp_table )
- {
- integer cur = (integer) UI::QueryWidget( `id(`mp_table),
- `CurrentItem );
- integer sel_num = 0;
- integer i = 0;
- while( i<cur )
- {
- if( raid_enab[i]:false )
- {
- sel_num = sel_num + 1;
- }
- i=i+1;
- }
- string dev = "";
- if( !raid_enab[i]:false )
- {
- dev = Storage::GetDeviceName( "/dev/md",
- raid_list[sel_num]:255 );
- sel_num = sel_num + 1;
- }
- raid_enab[i] = !raid_enab[i]:false;
- UI::ChangeWidget(`id(`mp_table), `Item(cur, 1), dev );
- UI::ChangeWidget(`id(`mp_table), `Item(cur, 0),
- // label text
- size(dev)==0?_("No"):_("Yes") );
- i = cur+1;
- while( i<size(raid_enab) )
- {
- if( raid_enab[i]:false )
- {
- dev = Storage::GetDeviceName( "/dev/md",
- raid_list[sel_num]:255 );
- sel_num = sel_num + 1;
- UI::ChangeWidget(`id(`mp_table), `Item(i, 1), dev );
- }
- i = i+1;
- }
- }
-
- if( ret == `next )
- {
- integer i = 0;
- list md_part = [];
- while( i<size(raid_enab) )
- {
- if( raid_enab[i]:false )
- {
- string dev = sformat( "/dev/md%1", raid_list[i]:255 );
- map rp = $[ "nr" : raid_list[i]:255,
- "device" : dev,
- "raid_type" : "multipath",
- "type" : `sw_raid,
- "fsid" : Partitions::fsid_native,
- "size_k" : 0, // dummy
- "create" : true,
- "used_fs" : Partitions::DefaultFs() ];
- map p = $[];
- foreach( string device, (list<string>)at[i]:[],
- ``{
- p = Storage::GetPartition( tg, device );
- p["used_by_type"] = `UB_MD;
- p["used_by"] = substring(dev,5);
- if( p["fsid"]:0 != Partitions::fsid_raid )
- {
- if( !p["change_fsid"]:false )
- {
- p["change_fsid"] = true;
- p["ori_fsid"] = p["fsid"]:0;
- p["ori_fstype"] = p["fstype"]:"";
- }
- p["fsid"] = Partitions::fsid_raid;
- p["fstype"] =
- Partitions::FsIdToString(Partitions::fsid_raid);
- }
- y2debug( "p1 %1", p );
- tg = (map<string,map>)Storage::SetPartition( tg, p );
- });
-
- integer mdsize = raid_size_byte(rp);
- y2milestone( "mdsize=%1", mdsize );
- rp["size_k"] = mdsize / 1024;
- md_part = add( md_part, rp );
- y2milestone( "enabled %1 num:%2 entry:%3", i,
- raid_list[i]:255, at[i]:[] );
- y2milestone( "rp %1", rp );
- }
- i = i+1;
- }
- if( size(md_part)>0 )
- {
- tg = Storage::GetTargetMap();
- tg["/dev/md","partitions"] =
- merge( tg["/dev/md","partitions"]:[], md_part );
- Storage::SetTargetMap( tg );
- }
- }
- }
- while( ret != `back && ret !=`next && ret !=`abort );
- y2milestone( "ret %1", ret );
- return ret;
- }
-
- /**
- * ChooseRaidType Dialog
- * @parm what -> `settings or `wizard
- * @return symbol
- */
- define symbol ChooseRaidType(symbol what)
- ``{
- integer raidnr = 0;
- map raidp = $[];
-
- Storage::CreateTargetBackup("raid");
-
- y2milestone( "ChooseRaidType what:%1", what );
-
- map<string,map> tg = Storage::GetTargetMap();
- string rdev = Storage::GetWizardKey();
- if( size(rdev)==0 )
- {
- raidnr = get_free_raid_nr( tg, 0 );
- rdev = sformat( "/dev/md%1", raidnr );
- Storage::SetWizardKey(rdev);
- }
- else
- {
- raidp = Storage::GetPartition( tg, rdev );
- raidnr = raidp["nr"]:0;
- }
-
- y2milestone( "ChooseRaidType raidp raidp=%1", raidp );
- y2milestone( "ChooseRaidType nr=%1 dev:%2", raidnr, rdev );
-
- /////////////////////////////////////////////////////////////////
- // Choose Raid Type ...
- /////////////////////////////////////////////////////////////////
-
- // heading text
- string caption = _("RAID Wizard: Step 1.");
- term contents =
- get_choose_raid_type_contents(raidp["raid_type"]:"raid1", what );
-
- if( what == `wizard )
- {
- Wizard::SetContentsButtons(caption, contents,
- ChooseRaidTypeHelp(),
- Label::BackButton(),
- Label::NextButton());
- }
- else if ( what == `settings )
- {
- contents = add( contents,
- `HBox(
- // popup create partition:
- `PushButton(`id(`ok), `opt(`default),
- Label::OKButton() ),
- // popup create partition:
- `PushButton(`id(`cancel), Label::CancelButton() )
- ));
-
- UI::OpenDialog( `opt(`decorated ),
- `HBox(
- `HWeight(50, `RichText( ChooseRaidTypeHelp() )),
- `HStretch(),
- `HSpacing(1),
- `HWeight(70, contents ),
- `HSpacing(1),
- `HStretch()
- ));
- }
- else
- {
- y2error( " Error what in ChooseRaidType must be symbol `wizard or `settings");
- }
-
- boolean new_raid = size(raidp)==0;
- symbol ret = `none;
- y2milestone( "ChooseRaidType new_raid:%1", new_raid );
- do
- {
- ret = (symbol)UI::UserInput();
-
- if( contains( [ `next, `ok, `accept ], ret ))
- {
- ////////////////////////////////////////////////////////////
- // Create initial raid datastructure, which comes to
- // /dev/md[partitions]
-
- string raidtype = (string)UI::QueryWidget( `id("raid_type"),
- `CurrentButton );
- y2milestone( "ChooseRaidType raidtype:%1", raidtype );
-
- integer chunk_size = 4;
-
- if( raidtype == "raid5" ) chunk_size = 128;
- if( raidtype == "raid0" ) chunk_size = 32;
-
- if( raidp == $[] || what == `settings )
- {
- string mprop = GetMountPointProposal( tg, [] );
- symbol used_fs = Partitions::DefaultFs();
- if( mprop == Partitions::BootMount() )
- {
- used_fs = Partitions::DefaultBootFs();
- }
- Storage::CreateMd( raidnr, raidtype );
- raidp = $[ "device" : rdev,
- "format" : true,
- "mount" : mprop,
- "used_fs" : used_fs ];
- Storage::ChangeVolumeProperties( raidp );
- raidp = Storage::GetPartition( Storage::GetTargetMap(), rdev );
- y2milestone( "ChooseRaidType raidp:%1", raidp );
- }
- else
- Storage::ChangeMdType( raidnr, raidtype );
- Storage::ChangeMdChunk( raidnr, chunk_size );
- ret = `next;
- }
- else if( ret == `back && what==`wizard && !new_raid )
- {
- // popup text %1 will be replaces with button text
- string txt = sformat( _("Changes made to your RAID setup so far will be
- lost if you exit the dialog with %1.
- Continue?
- "),
- deletechars(Label::BackButton(),"&") );
- if( !Popup::ContinueCancel( txt ))
- {
- ret = `again;
- }
- }
- }
- while( !contains( [`next, `back ], ret ));
-
- if( what == `settings)
- {
- UI::CloseDialog();
- }
-
- if( ret == `back && what==`wizard )
- {
- y2milestone( "ChooseRaidType raidp:%1", raidp );
- if( raidp["create"]:false )
- {
- string md = sformat( "md%1", raidp["nr"]:0 );
- list<map> parts = filter( map p, all_raid_partitions(tg),
- ``(p["used_by"]:""==md));
- foreach( map p, parts,
- ``{
- Storage::UnchangePartitionId( p["device"]:"" );
- });
- y2milestone( "ChooseRaidType parts:%1", parts );
- Storage::DeleteDevice( "/dev/md", raidp["device"]:"" );
- }
- }
- y2milestone( "ChooseRaidType ret %1", ret );
- return ret;
- }
-
- /**
- * Help for RaidDevices Dialog
- * @return string
- */
- define string RaidDevicesHelp()
- ``{
- // help text, richtext format
- string helptext = _("<p><b>Add partitions to your RAID.</b> According to
- the RAID type, the usable disk size is the sum of these partitions (RAID0), the size
- of the smallest partition (RAID 1), or (N-1)*smallest partition (RAID 5).</p>
- ");
-
- // help text, richtext format
- helptext = helptext + _("<p>Generally, the partitions should be on different drives,
- to get the redundancy and performance you want.</p>
- ");
-
- // help text, richtext format
- helptext = helptext + _("<p><b>Expert options:</b><br>Here, set
- things like chunk size to get the best performance
- out of your system. These settings are used for all partitions of this RAID.</p>
- ");
-
- return helptext;
- }
-
-
- /**
- * Popup to display an error when changing an existing raid.
- *
- * in dev: device name of the raid device
- */
- define void CannotEditExistingRaid( string dev )
- ``{
- // Error popup text
- Popup::Error(sformat( _("The RAID to change (%1) is already created on disk.
- It can no longer be changed. To change %1,
- remove it and create it again.
- "),dev));
- };
-
-
- /**
- * partition add partition widget table.
- * @return term
- */
- define term get_raid_devices_content( symbol what, string current_raid_text,
- list all_raids, string size_md )
- ``{
- term top = `HBox(
- `Left (`Label (current_raid_text)),
- // Label in raid -wf
- `Label (_("Size:")),
- `Label (`id(`raid_size), `opt( `outputField), "---------")
- );
-
- if( what == `settings )
- {
- top = `HBox(
- `Left(`VBox(
- `ReplacePoint(`id(`raids_rp),
- `ComboBox(`id(`raids),
- `opt(`notify),
- // label text
- _("RA&ID:"), all_raids)),
- `PushButton( `id(`md_raid_edit),
- // label text
- `opt(`hstretch), _("O&ptions"))
- )),
-
- `HSpacing(0.5),
- // label text
- `Left(`Label(_("Size:"))),
- `Left(`Label( `id(`raid_size),
- `opt( `hstretch, `outputField), "-------" )),
- `HWeight(1,`HStretch()),
- `Right(`VBox(
- `PushButton( `id(`md_raid_remove),
- `opt(`hstretch),
- // button text
- _("Remo&ve RAID")),
- `PushButton( `id(`md_raid_add),
- `opt(`hstretch),
- // button text
- _("Add RAI&D"))))
- );
- }
-
- return( `HBox(
- `HSpacing(1),
- `VBox(
- `VSpacing (0.5),
- top,
- `VSpacing (0.2),
- `Table(`id(`raid_table), `opt(`notify),
- // table header
- `header(_(" Device "),
- // table header
- `Right(_(" Size ")),
- // table header
- `Center(_(" Type ")),
- // table header
- `Center(_(" RAID "))),
- []
- ),
- `HBox (
- // Button in RAID-WF
- `PushButton (`id (`raid_add), _("A&dd")),
- // Button in RAID-WF
- `PushButton (`id (`raid_remove), _("&Remove"))
- ),
- `VSpacing (0.5)
- ),
- `HSpacing(1)
-
- )
- );
- };
-
-
- /**
- * RaidExpertDlgHelp
- * @return string
- */
- define string RaidExpertDlgHelp()
- ``{
- // help text
- string helptext_edit_raid = _("<p><b>chunk size:</b><br>It is the smallest \"atomic\" mass
- of data that can be written to the devices. A reasonable chunk size for RAID 5 is 128KB. For RAID 0,
- 32 KB is a good starting point. For RAID 1, the chunk size does not affect the array very much.</p>
- ");
-
- // help text
- helptext_edit_raid = helptext_edit_raid + _("<p><b>parity algorithm:</b><br>The parity algorithm to use with RAID5.
- Left-symmetric is the one that offers maximum performance on typical disks with rotating platters.</p>
- ");
-
- return helptext_edit_raid;
- };
-
- /**
- * raidExpertDlg dialog
- * edit expert options
- */
- define map<string,any>
- RaidExpertDlg( symbol what, string device, map<string,any> cur_raid,
- map<symbol,map> file_systems, boolean edit_raid_type,
- map<string,map> targetMap )
- ``{
- string raid_type = cur_raid["raid_type"]:"raid1";
- // heading text
- string caption = sformat(_("Raid settings %1"), device );
- boolean created = cur_raid["create"]:false;
-
- term contents = `HBox(
- FormatDlg( cur_raid, file_systems ),
- `HSpacing(2),
- `VBox(
- `Top( RaidOptionsDlg( cur_raid, true )),
- `Bottom(
- `ReplacePoint( `id(`mount_dlg_rp),
- MountDlg( cur_raid, [] )))
- )
- );
-
-
- if( what == `settings )
- {
- contents = `VBox(
- `Heading(caption),
- `VSpacing(1),
- `VStretch(),
- contents,
- `VSpacing(1),
- `VStretch(),
- `HBox(
- // popup create partition:
- `PushButton(`id(`ok), `opt(`default),
- Label::OKButton() ),
- // popup create partition:
- `PushButton(`id(`cancel), Label::CancelButton() )
- ));
-
-
-
- /////////////////////////////////////////////////////////////
- // Open main dialog for Raid
- /////////////////////////////////////////////////////////////
- if( ! UI::OpenDialog( `opt(`decorated ),
- `HBox(
- `HWeight(30,`RichText(RaidExpertDlgHelp())),
- `HStretch(),
- `HSpacing(1),
- `HWeight(70, contents ),
- `HSpacing(1),
- `HStretch()
- )))
- return cur_raid;
- }
- else
- {
- // heading text
- Wizard::SetContentsButtons(_("RAID Wizard Step 3:"),
- `HBox(
- `HSpacing(),
- `VBox(
- `VSpacing(),
- `HVCenter(`HVSquash(contents)),
- `VSpacing(),
- `VSpacing(1)
- ),
- `HSpacing()
- ),
- RaidExpertDlgHelp(),
- Label::BackButton(), Label::FinishButton());
-
- }
-
-
- ////////////////////////////////////////////////////////////////
- // configure main dialog for the first call
-
- ChangeExistingSymbolsState( [`raid_combo], false);
-
- UI::ChangeWidget( `id(`raid_combo), `Value, raid_type );
- UI::ChangeWidget( `id(`chunk_size), `Value, cur_raid["chunk_size"]:4 );
- UI::ChangeWidget( `id(`parity), `Enabled, created && raid_type=="raid5" );
- UI::ChangeWidget( `id(`chunk_size), `Enabled,
- created && raid_type!="multipath" );
-
- map<string,any> retval = eval(cur_raid);
- symbol ret = `ok;
-
- retval = HandlePartWidgetChanges( true, ret, file_systems, cur_raid, retval );
-
- repeat
- {
- ret = (symbol)UI::UserInput();
- y2debug( "DlgRaid %1", ret);
-
- ////////////////////////////////////////////////////////////
- if( ret != `cancel )
- {
- retval = HandlePartWidgetChanges( false, ret, file_systems,
- cur_raid, retval );
-
- if( edit_raid_type )
- retval["raid_type"] =
- UI::QueryWidget(`id(`raid_combo), `Value);
-
- retval["chunk_size"] = UI::QueryWidget(`id(`chunk_size), `Value);
- retval["parity_algorithm"] = UI::QueryWidget(`id(`parity), `Value);
- y2milestone( "RaidExpertDlg retval:%1", retval );
- }
-
- if( ret == `raid_combo )
- {
- UI::ChangeWidget( `id(`parity), `Enabled,
- created && raid_type=="raid5" );
- UI::ChangeWidget( `id(`chunk_size), `Enabled,
- created && raid_type!="multipath" );
- }
-
- if( ret == `ok || ret == `next )
- {
- map ret_mp = CheckOkMount( retval["device"]:"", cur_raid, retval );
- retval = ret_mp["map"]:$[];
- if( !ret_mp["ok"]:false )
- {
- if( ret_mp["field"]:`none != `none )
- UI::SetFocus(`id( ret_mp["field"]:`none ));
- ret = `again;
- continue;
- }
-
- ret_mp = CheckDeviceFinalOk( retval );
- if( !ret_mp["ok"]:false )
- {
- ret = `again;
- }
- else
- {
- retval = ret_mp["map"]:$[];
- y2milestone( "RaidExpertDlg retval:%1", retval );
- }
- }
-
- } until( ret == `ok || ret == `cancel || ret == `next ||
- ret == `back || ret == `abort );
-
- y2milestone( "ret:%1 retval=%2", ret, retval );
-
- if( ret == `back || ret == `next )
- {
- retval["symbol"] = ret;
- }
- else
- {
- UI::CloseDialog();
- }
-
- if( ret == `ok || ret == `next || ret == `back )
- {
- y2milestone( "RaidExpertDlg retval:%1", retval );
- Storage::ChangeVolumeProperties( retval );
- if( edit_raid_type && haskey( retval, "raid_type" ))
- Storage::ChangeMdType( retval["nr"]:0, retval["raid_type"]:"raid1" );
- if( haskey( retval, "chunk_size" ))
- Storage::ChangeMdChunk( retval["nr"]:0, retval["chunk_size"]:4 );
- if( retval["raid_type"]:"raid1"=="raid5" &&
- haskey( retval, "parity_algorithm" ))
- Storage::ChangeMdParity( retval["nr"]:0,
- retval["parity_algorithm"]:"" );
- return retval;
- }
- return cur_raid;
- }
-
- /**
- * AddRaidDevices dialog
- *
- * Choose free partitions and add them to the raid.
- * additionally you can edit the raid options like chunk size
- * in -
- * out:
- */
- define symbol RaidDevices( symbol what )
- ``{
- y2milestone( "RaidDevices what %1", what );
- Storage::CreateTargetBackup("raid");
-
- string raiddev = Storage::GetWizardKey();
- y2milestone( "RaidDevices Current raid; raiddev=%1", raiddev );
- map<string,map> tg = Storage::GetTargetMap();
- map<string,any> raidp = Storage::GetPartition( tg, raiddev );
- y2milestone( "RaidDevices raidp=%1", raidp );
-
- /* e.g.: subdevraidindex = 1; */
- integer raidnr = raidp["nr"]:0;
- // heading text
- string caption = _("RAID Wizard Step 2:");
-
- /* key for subdev that can assigned to a raid */
- string pdevice = "";
-
- if( what == `settings )
- {
- // heading text
- caption = _("RAID settings");
- }
-
- list<map> parts = [];
- list table = [];
-
- Wizard::SetContentsButtons( caption,
- get_raid_devices_content(what,
- // label text
- sformat(_("Current RAID: /dev/md%1"), raidnr),
- get_raid_devices(tg,raidp["nr"]:0),
- ""
- ),
- RaidDevicesHelp(),
- Label::BackButton(), Label::NextButton() );
-
- UI::SetFocus( `id(`raid_table));
-
- //////////////////////////////////////////////////////////////////////
- // mainloop
- //////////////////////////////////////////////////////////////////////
-
- symbol ret = `start;
-
- tg = Storage::GetTargetMap();
- repeat
- {
- //////////////////////////////////////////////////////////
- // Raid ComboBox
- if( what == `settings )
- {
- raiddev = (string)UI::QueryWidget(`id(`raids), `Value );
- y2milestone( "RaidDevices Selected Raid in ComboBox; raiddev=%1",
- raiddev );
- raidp = Storage::GetPartition( tg, raiddev );
- raidnr = raidp["nr"]:255;
- }
- y2milestone( "RaidDevices Current raid; raiddev=%1", raiddev );
- y2milestone( "RaidDevices ret %1", ret );
-
- ///////////////////////////////////////////////////////////
- // Update raid widget table
- if( ret != `raids || ret == `start )
- {
- parts = get_possible_rds( tg );
- if( what == `wizard )
- {
- parts = filter( map part, parts,
- ``( part["used_by"]:"" == sformat("md%1",raidnr) ||
- size(part["used_by"]:"")==0 ));
- }
- y2milestone( "RaidDevices parts %1", parts );
-
- /////////////////////////////////////////////////////////////////
- // Show the current state:
- table = get_raid_widget_table( parts );
-
- UI::ChangeWidget( `id(`raid_table), `Items, table);
- }
-
- UI::ChangeWidget( `id(`raid_size), `Value, raid_size_str( raidp ));
-
- if( pdevice != "" && (ret == `raid_add || ret == `raid_remove) )
- {
- UI::ChangeWidget( `id(`raid_table), `CurrentItem, pdevice);
- }
-
-
- /////////////////////////////////////////////////////////////////
- // Wait for User input
- ret = (symbol)UI::UserInput();
- y2milestone( "RaidDevices ret %1", ret );
-
- /////////////////////////////////////////////////////////////////
- // Edit raid settings - not in wizard
- if( ret == `md_raid_edit )
- {
- RaidExpertDlg( `settings, raiddev, raidp,
- FileSystems::GetAllFileSystems(true,true),
- false, tg );
- tg = Storage::GetTargetMap();
- raidp = Storage::GetPartition( tg, raiddev );
- }
-
- /////////////////////////////////////////////////////////////////
- // Add a new raid
- if( ret == `md_raid_add )
- {
- if( !check_raid_possible( tg ))
- {
- ret = `again;
- continue;
- }
-
- ChooseRaidType( `settings );
- tg = Storage::GetTargetMap();
- y2milestone( "RaidDevices new raid:%1", Storage::GetWizardKey() );
- if( Storage::GetWizardKey()!=raiddev )
- {
- raiddev = Storage::GetWizardKey();
- y2milestone( "RaidDevices new raid:%1", raiddev );
- UI::ChangeWidget( `id(`raids), `Value, raiddev );
- raidp = Storage::GetPartition( tg, raiddev );
- }
- }
-
- /////////////////////////////////////////////////////////////////
- // Remove a new raid (2//dev/md ) - not in wizard
- if( ret == `md_raid_remove )
- {
- // popup text
- if ( Popup::YesNo ( sformat(_("Do you really want to delete partition %1?"), "/dev/md"+raidnr )))
- {
- Storage::DeleteDevice( "/dev/md", raiddev );
- tg = Storage::GetTargetMap();
- }
- }
-
- /////////////////////////////////////////////////////////////////
- // Update Raid ComboBox - not in wizard
- if( ret == `md_raid_add || ret == `md_raid_remove )
- {
- new_raid_list( get_raid_devices( tg, raidp["nr"]:0 ));
- raiddev = (string)UI::QueryWidget(`id(`raids), `Value );
- y2milestone( "RaidDevices raiddev %1", raiddev );
- raidp = Storage::GetPartition( tg, raiddev );
- raidnr = raidp["nr"]:0;
- }
-
- if( ret == `raid_table )
- {
- pdevice = (string)UI::QueryWidget( `id(`raid_table), `CurrentItem );
- ret = isItemRd(tg,pdevice) ? `raid_remove : `raid_add;
- }
-
- /////////////////////////////////////////////////////////////
- // Add a new physical volume to a raid e.g. assign 1//dev/hda
- // to 1//dev/md
- if( ret == `raid_add )
- {
- pdevice = (string)UI::QueryWidget( `id(`raid_table), `CurrentItem );
-
- if( CheckItemIsNotRaid( tg, pdevice ) &&
- CheckRaidNumbers( raidnr ) )
- {
- if( raidp["create"]:false )
- {
- Storage::SetPartitionId( pdevice, Partitions::fsid_raid );
- Storage::ExtendMd( raidnr, pdevice );
- tg = Storage::GetTargetMap();
- raidp = Storage::GetPartition( tg, raiddev );
- }
- else
- {
- CannotEditExistingRaid( raiddev );
- ret = `again;
- }
- }
- }
-
-
- /////////////////////////////////////////////////////////////
- // Delete a new physical volume e.g. remove 1//dev/hda from 1//dev/md
- if( ret == `raid_remove )
- {
- pdevice = (string)UI::QueryWidget(`id(`raid_table), `CurrentItem);
-
- if( CheckItemIsRaid( tg, pdevice) )
- {
- if( raidp["create"]:false )
- {
- Storage::UnchangePartitionId( pdevice );
- Storage::ShrinkMd( raidnr, pdevice );
- tg = Storage::GetTargetMap();
- raidp = Storage::GetPartition( tg, raiddev );
- }
- else
- {
- CannotEditExistingRaid( raiddev );
- ret = `again;
- }
- }
- }
-
-
- if (ret == `next)
- {
- ///////////////////////////////////////////////////////
- // check if enough disks are attached to the raid
- list<map> parts = (list<map>)Storage::GetDisk( tg, "/dev/md" )["partitions"]:[];
- foreach( map part, parts,
- ``{
- if( part["create"]:false )
- {
- string raid_type = part["raid_type"]:"raid1";
- integer nr_of_parts =
- getNrOfParts( tg, sformat("%1", part["nr"]:0) );
- string raid = part["device"]:"";
- boolean ok = Storage::CheckMd(part["nr"]:0)==0;
- if( !ok )
- {
- string txt = "";
- if( raid_type=="raid0" )
- {
- // Error popup text
- txt = sformat(_("For RAID 0, add at least two partitions to %1."), raid );
- }
- else if( raid_type=="raid1" )
- {
- // Error popup text
- txt = sformat(_("For RAID 1, add at least two partitions to %1."), raid );
- }
- else if( raid_type == "raid5" )
- {
- // Error popup text
- txt = sformat(_("For RAID 5, add at least three partitions to %1."), raid);
- }
- else if( raid_type == "raid6" )
- {
- // Error popup text
- txt = sformat(_("For RAID 6, add at least four partitions to %1."), raid);
- }
- else if( raid_type == "raid10" )
- {
- // Error popup text
- txt = sformat(_("For RAID 10, add at least two partitions to %1."), raid);
- }
- else if( raid_type == "multipath" )
- {
- // Error popup text
- txt = sformat(_("For Multipath raid, add at least two partitions to %1."), raid);
- }
- Popup::Error(txt);
- ret = `again;
- }
- }
- });
- }
- }
- until( ret == `next || ret == `back || ret == `cancel || ret == `abort );
- return ret;
- }
-
-
- /**
- * RaidExpertWizard
- *
- */
- define symbol RaidExpertWizard()
- ``{
- string raiddev = Storage::GetWizardKey();
- map<string,map> tg = Storage::GetTargetMap();
- map<string,any> raidp = Storage::GetPartition( tg, raiddev );
-
- raidp = RaidExpertDlg( `wizard, raidp["used_by"]:"", raidp,
- FileSystems::GetAllFileSystems(true, true),
- false, tg );
-
- symbol ret = raidp["symbol"]:`next;
- y2milestone( "RaidExpertWizard ret:%1", ret );
- return ret;
- }
-
-
-
- }
-