home *** CD-ROM | disk | FTP | other *** search
Wrap
/** * File: * controller.ycp * * Module: * Configuration of disk controller * * Summary: * Main file * * Authors: * THomas Fehr <fehr@suse.de> * * $Id: controller.ycp 27442 2006-01-30 14:53:09Z fehr $ * */ { textdomain "storage"; import "Wizard"; import "Misc"; /*import "Bootloader";*/ import "Label"; import "Popup"; list<string> initrd = []; list<string> initrd_orig = []; map<string,string> params = $[]; map<string,string> params_orig = $[]; define string HelpText() ``{ // help text return( _("<p><big><b>Disk Controller Configuration</b></big></p> <p>Here, configure disk controllers by modifying the corresponding kernel module.</p> <p>The table at top contains the controllers to configure. If there is more than one controller, select the controller by clicking a line in the table. The order in the table determines the order in which kernel modules are loaded. Use <b>Move Up</b> and <b>Move Down</b> to change the order. </p> <p><b>Module to Use</b> selects the kernel module to use for the current controller. Alternative modules are available for some controllers.</p> <p>The module status is shown in <b>Module Currently Loaded</b>. With <b>Load Module in initrd</b> set whether the module should be loaded during boot.</p> <p>For <b>Module Parameters</b>, enter any parameters for the module. This is often not needed.</p> <p><b>Test Loading of Module</b> tests whether the module can be loaded with the specified parameters. This test is recommended if you have made changes.</p> ")); } define term ModComboBox( list modules ) ``{ return( `ComboBox( `id(`module), `opt(`editable,`notify), // label text _("&Module to Use"), modules )); }; define term InitCheckBox( boolean val ) ``{ return( `CheckBox( `id(`initrd), `opt(`notify), // button text, initrd should be left as-is _("&Load Module in initrd"), val )); }; define void SetModule( map cont ) ``{ integer num = 0; list mod = maplist( map entry, cont["drivers"]:[], ``{ term it = `item( `id(num), mergestring(entry["modules",0]:[]," "), cont["modnum"]:0==num ); num = num+1; return( it ); }); y2milestone( "mod=%1", mod ); UI::ReplaceWidget( `id(`rep_mod), ModComboBox( mod )); if( !haskey( cont, "modnum" )) { cont["modnum"] = 0; } }; define void SetLoaded( string mod ) ``{ SCR::UnmountAgent (.proc.modules); map lmod = (map)SCR::Read(.proc.modules); // label text string val = haskey(lmod, mod) ? _("Yes") : _("No"); UI::ChangeWidget( `id(`loaded), `Value, val ); y2milestone( "Loaded=%1", val ); } define void SetInitrd( string mod ) ``{ boolean val = contains(initrd,mod); UI::ReplaceWidget( `id(`rep_initrd), InitCheckBox( val )); y2milestone( "Initrd=%1", val ); } define void SetParams( string mod, string defaultp ) ``{ string param = defaultp; if( haskey( params, mod )) { param = params[mod]:""; } else if( haskey( params_orig, mod )) { param = params_orig[mod]:""; } else { list opts = (list)SCR::Read( .modules.options ); y2milestone( "ppts=%1", opts ); if( contains( opts, mod )) { map<string,string> options = (map<string,string>)SCR::Read( .modules.options, mod ); y2milestone( "options %1 = %2", mod, options ); foreach( string k, string v, options, ``{ if( size(param)>0 ) { param = param + " "; } if( size(v)==0 ) { param = param + k; } else { param = param + k + "=" + v; } }); } params_orig[mod] = param; } UI::ChangeWidget( `id(`param), `Value, param ); } define string ModNameChanged( map cont, integer num, integer old ) ``{ string oldmod = cont["drivers",old,"modules",0,0]:""; string mod = cont["drivers",num,"modules",0,0]:""; y2milestone( "mod=%1 old=%2", mod, old ); if( oldmod != mod ) { params[oldmod] = (string)UI::QueryWidget( `id(`param), `Value ); if( contains( initrd, oldmod ) ) { initrd = maplist( string e, initrd, ``{ return( e==oldmod ? mod : e ); }); y2milestone( "new initrd=%1", initrd ); } } SetLoaded( mod ); SetInitrd( mod ); SetParams( mod, cont["drivers",num,"modules",1]:"" ); return( mod ); } define integer TermToId( term t ) ``{ return( (integer)(t[0,0]:0) ); } define integer GetArrayPos( list l, integer num ) ``{ integer i = 0; while( i < size(l) && TermToId(l[i]:`Empty())!=num ) { i = i+1; } return( i ); } define string SetAllData( map cont, list clist, integer cur ) ``{ string ret = ""; if( size(cont)>0 ) { SetModule( cont ); integer num = (integer)UI::QueryWidget( `id(`module), `Value ); ret = ModNameChanged( cont, num, num ); UI::ChangeWidget( `id(`moveup), `Enabled, GetArrayPos(clist,cur)>0 ); UI::ChangeWidget( `id(`movedown), `Enabled, GetArrayPos(clist,cur)<size(clist)-1 ); } return( ret ); } define boolean TestLoad( map cont ) ``{ y2milestone( "num %1 drivers %2", cont["modnum"]:0, cont["drivers"]:[] ); string cmd = ""; foreach( map e, cont["drivers"]:[], ``{ foreach( list m, e["modules"]:[], ``{ if( size(m[0]:"")>0 ) { cmd = "/sbin/rmmod -r " + m[0]:""; y2milestone( "cmd %1", cmd ); SCR::Execute( .target.bash, cmd ); } }); }); map m = cont["drivers",cont["modnum"]:0]:$[]; if( size(m)>0 && size(m["modules"]:[])>0 ) { boolean ok = true; string param = (string) UI::QueryWidget( `id(`param), `Value ); integer num = 0; foreach( list d, m["modules"]:[], ``{ cmd = m["modprobe"]:false ? "/sbin/modprobe " : "/sbin/insmod "; y2milestone( "cmd %1", cmd ); cmd = cmd + d[0]:"" + " "; y2milestone( "cmd %1", cmd ); cmd = cmd + (num==0 ? param : d[1]:""); y2milestone( "cmd %1", cmd ); map ret = (map)SCR::Execute( .target.bash_output, cmd ); if( ret["exit"]:1 == 1) { // error popup text; stderr=standard error string text = sformat( _(" Error loading module. Executed command was: %1 stderr was: %2 "), cmd, ret["stderr"]:"" ); Popup::Error( text ); ok = false; } }); if( ok ) { // popup text, %1=module name Popup::Message( sformat(_("Module %1 loaded successfully."), m["modules",0,0]:"" )); } } } Wizard::OpenAbortApplyFinishDialog(); list<map> dev = []; foreach( map entry, (list<map>)SCR::Read(.probe.storage), ``{ map conf = (map)SCR::Read(.probe.status, entry["unique_key"]:""); y2milestone( "entry:%1", entry ); y2milestone( "conf:%1", conf ); if( conf["available"]:`no != `no && size(entry["drivers"]:[])>0 && find( map e, dev, ``(e["bus"]:""==entry["bus"]:"" && e["slot_id"]:0==entry["slot_id"]:0 && e["bus_id"]:0==entry["bus_id"]:0))==nil ) { entry["conf"] = conf; dev = add( dev, entry ); } }); /* dev = add( dev, $[ "conf" : $[ "configured" : `new ], "drivers" : [ $[ "modprobe" : false, "modules" : [ [ "loop_fish2", "" ]]]], "model" : "Loop driver" ] ); */ boolean first_new = true; integer cur_num = 0; integer num = 0; list<term> clist = maplist( map entry, dev, ``{ term it = `item( `id(num) ); it = add( it, entry["model"]:"" ); if( entry["conf","configured"]:`no==`new ) { // label text it = add( it, _("Yes")); if( first_new ) { first_new = false; cur_num = num; } } else { // label text it = add( it, _("No") ); } num = num+1; return( it ); }); string tmp = Misc::SysconfigRead( .sysconfig.kernel.INITRD_MODULES, ""); initrd_orig = filter( string e, splitstring( tmp, " " ), ``(size(e)>0) ); initrd = initrd_orig; y2milestone( "initrd %1", tmp ); clist = sort( term a, term b, clist, ``{ boolean ret = true; integer numa = TermToId(a); integer numb = TermToId(b); list pos_mod = []; foreach( map e, dev[numa,"drivers"]:[], ``{ if( size(e["modules",0,0]:"")>0 ) pos_mod = add( pos_mod, e["modules",0,0]:""); }); integer initrda = -1; integer initrdb = -1; integer posm = 0; integer posi = 0; while( posm < size(pos_mod) && initrda==-1 ) { posi = 0; while( posi<size(initrd) && initrda==-1 ) { if( initrd[posi]:"" == pos_mod[posm]:"" ) { initrda = posi; } posi = posi + 1; } posm = posm + 1; } pos_mod = []; foreach( map e, dev[numb,"drivers"]:[], ``{ if( size(e["modules",0,0]:"")>0 ) pos_mod = add( pos_mod, e["modules",0,0]:""); }); posm = 0; while( posm < size(pos_mod) && initrdb==-1 ) { posi = 0; while( posi<size(initrd) && initrdb==-1 ) { if( initrd[posi]:"" == pos_mod[posm]:"" ) { initrdb = posi; } posi = posi + 1; } posm = posm + 1; } y2debug( "a:%1 initrda:%2 b:%3 initrdb:%4", numa, initrda, numb, initrdb ); if( initrda!=-1 && initrdb!=-1 ) { ret = initrda<=initrdb ; } else if( initrda==-1 && initrdb==-1 ) { boolean newa = dev[numa,"conf","configured"]:`no == `new; boolean newb = dev[numb,"conf","configured"]:`no == `new; if( newa && !newb ) ret = false; else ret = true; } else { ret = initrda!=-1; } ret = ret && a!=b; y2debug( "ret %1", ret ); return( ret ); }); y2milestone( "clist=%1", clist ); term dialog = `VBox( `VSpacing(1), /*`Left(*/`HBox( `HWeight(70, `Table( `id(`controller), `opt(`notify,`immediate,`keepSorting), // table heading text `header( _("Disk Controller"), _("New")), clist )), `HWeight(20, // button text `VBox( `PushButton( `id(`moveup), _("Move &Up") ), `PushButton( `id(`movedown), // button text _("Move &Down")))))/*)*/, `VSpacing(1), /*`Left(*/`HBox( `HWeight(40, `ReplacePoint(`id(`rep_mod), ModComboBox( [] ) )), `HWeight(60, `HStretch()) )/*)*/, `VSpacing(1), // provides Yes or No status info `Left(`HBox( `Label( _("Module Currently Loaded:")), `HSpacing(2), // label text `Label( `id(`loaded), _("Yes") ))), `VSpacing(1), `Left(`ReplacePoint(`id(`rep_initrd), InitCheckBox( false ))), `VSpacing(1), // label text `Left(`TextEntry( `id(`param), _("Module &Parameters"), "abdef" )), `VSpacing(1), // button text `PushButton( `id(`test_load), _("&Test Loading of Module")), `VSpacing(2) ); if( size(dev)==0 ) { // popup text Popup::Message( _("No configurable controller found.") ); UI::CloseDialog(); return `cancel; } // heading text Wizard::SetContents( _("Disk Controller Configuration"), dialog, HelpText(), true, true ); Wizard::SetDesktopIcon("controller"); UI::ChangeWidget( `id(`controller), `CurrentItem, cur_num ); string modname = SetAllData( dev[cur_num]:$[], clist, cur_num ); symbol ret = `none; boolean changed = false; y2milestone( "cur %1", dev[cur_num]:$[] ); do { ret = (symbol)UI::UserInput(); y2milestone( "ret = %1", ret ); if( ret == `controller ) { num = (integer)UI::QueryWidget( `id(`controller), `CurrentItem ); y2milestone( "num %1 cur_num %2", num, cur_num ); if( num != cur_num ) { cur_num = num; params[modname] = (string)UI::QueryWidget( `id(`param), `Value ); modname = SetAllData( dev[cur_num]:$[], clist, cur_num ); y2milestone( "controller module=%1", modname ); } } else if( ret == `moveup ) { changed = true; integer rpos = GetArrayPos( clist, cur_num ); term tmp = clist[rpos]:`Empty(); clist[rpos] = clist[rpos-1]:`Empty(); clist[rpos-1] = tmp; UI::ChangeWidget( `id(`controller), `Items, clist ); UI::ChangeWidget( `id(`controller), `CurrentItem, cur_num ); rpos = GetArrayPos( clist, cur_num ); y2milestone( "items=%1", clist ); y2milestone( "rpos=%1", rpos ); UI::ChangeWidget( `id(`moveup), `Enabled, rpos>0 ); UI::ChangeWidget( `id(`movedown), `Enabled, rpos<size(clist)-1 ); } else if( ret == `movedown ) { changed = true; integer rpos = GetArrayPos( clist, cur_num ); term tmp = clist[rpos]:`Empty(); clist[rpos] = clist[rpos+1]:`Empty(); clist[rpos+1] = tmp; UI::ChangeWidget( `id(`controller), `Items, clist ); UI::ChangeWidget( `id(`controller), `CurrentItem, cur_num ); rpos = GetArrayPos( clist, cur_num ); y2milestone( "items=%1", clist ); y2milestone( "rpos=%1", rpos ); UI::ChangeWidget( `id(`moveup), `Enabled, rpos>0 ); UI::ChangeWidget( `id(`movedown), `Enabled, rpos<size(clist)-1 ); } else if( ret == `module ) { num = (integer)UI::QueryWidget( `id(`module), `Value ); if( num != dev[cur_num,"modnum"]:0 ) { changed = true; modname = ModNameChanged( dev[cur_num]:$[], num, dev[cur_num,"modnum"]:0 ); dev[cur_num,"modnum"] = num; y2milestone( "module=%1", modname ); } } else if( ret == `initrd ) { changed = true; if( contains( initrd, modname )) { initrd = filter( string e, initrd, ``(e!=modname)); } else { initrd = add( initrd, modname ); } y2milestone( "initrd=%1", initrd ); } else if( ret == `test_load ) { TestLoad( dev[cur_num]:$[] ); SetLoaded( modname ); } else if( ret == `apply || ret == `finish ) { boolean mkinitrd = false; params[modname] = (string)UI::QueryWidget( `id(`param), `Value ); list<string> new_initrd = []; list<string> tlist = initrd; foreach( term e, clist, ``{ integer num = TermToId( e ); integer modnum = dev[num,"modnum"]:0; if( contains( tlist, dev[num,"drivers",modnum,"modules",0,0]:"" ) ) { foreach( list d, dev[num,"drivers",modnum,"modules"]:[], ``{ new_initrd = add( new_initrd, d[0]:"" ); tlist = filter( string e, tlist, ``(e!=d[0]:"")); if( size(params[d[0]:""]:"")==0 ) params[d[0]:""] = d[1]:""; mkinitrd = mkinitrd || size(d[1]:"")>0; }); } }); foreach( string e, initrd, ``{ if( size(e)>0 && !contains( new_initrd, e ) ) new_initrd = add( new_initrd, e ); }); string newinit = mergestring( new_initrd, " " ); string old = Misc::SysconfigRead( .sysconfig.kernel.INITRD_MODULES, ""); mkinitrd = mkinitrd || newinit != old; if( newinit != old ) { initrd = new_initrd; initrd_orig = new_initrd; } y2milestone( "make %3 new \"%1\" old \"%2\"", newinit, old, mkinitrd ); y2milestone( "params %1", params ); boolean writemod = false; foreach( string k, string v, params, ``{ y2milestone( "par orig:\"%1\" new:\"%2\"", params_orig[k]:"", v ); if( params_orig[k]:"" != v ) { mkinitrd = mkinitrd || contains(new_initrd,k); params_orig[k] = v; list<string> val = filter( string e, splitstring( v, " " ), ``(size(e)>0) ); y2milestone( "val %1", val ); map opts = $[]; foreach( string v, val, ``{ integer pos = search( v, "=" ); y2milestone( "v %1 pos %2", v, pos ); if( pos==nil ) { opts[v] = ""; } else { opts[substring(v,0,pos)] = substring( v, pos+1 ); } }); writemod = true; y2milestone( "k %1 opts:%2 write:%3", k, opts, writemod ); SCR::Write( .modules.options, opts, k ); } }); if( writemod ) { y2milestone( "writing modules.conf" ); SCR::Write( .modules, nil ); y2milestone( "finished writing modules.conf" ); } y2milestone( "mkinitrd %1", mkinitrd ); if( mkinitrd ) { SCR::Write( .sysconfig.kernel.INITRD_MODULES, newinit ); SCR::Write( .sysconfig.kernel, nil ); // busy popup text, mkinitrd is a case-sensitive command UI::OpenDialog( `Label( _("Executing mkinitrd...") ) ); integer exit = (integer)SCR::Execute( .target.bash, "/sbin/mkinitrd" ); UI::CloseDialog(); y2milestone( "exit /sbin/mkinitrd %1", exit ); if( exit != 0 ) { // popup text Popup::Error( _("Executing mkinitrd failed. Try executing /sbin/mkinitrd manually and checking the error messages. ")); } else { map boot_write = $[]; boot_write["insert_initrd"] = true; boot_write["initrd_changed_externally"] = true; boot_write["forbid_save_initrd"] = true; /* FIXME Bootloader::SetWriteMode( boot_write ); Bootloader::Write(); */ } } foreach( map entry, dev, ``{ if( size(entry["unique_key"]:"")>0 ) SCR::Write(.probe.status.configured, entry["unique_key"]:"", `yes); }); changed = false; SCR::Execute( .target.bash, "/sbin/hwscan --disk" ); SCR::Execute( .target.bash, "/sbin/hwscan --cdrom" ); } else if( ret == `abort || ret == `cancel ) { if( changed ) { // popup text if( !Popup::YesNo( _("You have unsaved changes. These changes will be lost if you abort now. Discard changes? "))) { ret = `continue; } } } } while( ret != `abort && ret!=`cancel && ret != `finish ); UI::CloseDialog(); }