home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / Kernel.ycp < prev    next >
Text File  |  2006-11-29  |  14KB  |  614 lines

  1. /**
  2.  * File:    modules/Kernel.ycp
  3.  * Package:    Installation
  4.  * Summary:    Kernel related functions and data
  5.  * Authors:    Klaus Kaempf <kkaempf@suse.de>
  6.  *        Arvin Schnell <arvin@suse.de>
  7.  *
  8.  * $Id: Kernel.ycp 33243 2006-10-03 10:39:03Z jsrain $
  9.  *
  10.  * <ul>
  11.  * <li>determine kernel rpm</li>
  12.  * <li>determine flags</li>
  13.  * <li>determine hard reboot</li>
  14.  * </ul>
  15.  */
  16.  
  17. {
  18.     module "Kernel";
  19.  
  20.     import "Arch";
  21.     import "Mode";
  22.     import "Linuxrc";
  23.     import "Stage";
  24.  
  25.     textdomain "base";
  26.  
  27. // kernel packages and binary
  28.  
  29. boolean kernel_probed = false;
  30.  
  31. /**
  32.  * the name of the kernel binary below '/boot'.
  33.  */
  34. string binary = "vmlinuz";
  35.  
  36. /**
  37.  * a list kernels to be installed.
  38.  */
  39. list<string> kernel_packages = [];
  40.  
  41. /**
  42.  * the final kernel to be installed after verification and
  43.  * availability checking
  44.  */
  45. string final_kernel = "";
  46.  
  47. // kernel commandline
  48.  
  49. boolean cmdline_parsed = false;
  50.  
  51. /**
  52.  * string the kernel vga paramter
  53.  */
  54. string vgaType = "";
  55.  
  56. /**
  57.  * if "suse_update" given in cmdline
  58.  */
  59. boolean suse_update = false;
  60.  
  61. /**
  62.  * string the kernel command line
  63.  * Don't write it directly, @see: AddCmdLine()
  64.  */
  65. string cmdLine = "";
  66.  
  67. // modules loaded on boot
  68.  
  69. /**
  70.  * List of changes in /etc/sysconfig/kernel:MODULES_LOADED_ON_BOOT
  71.  * Needs to be stored as a list of changes due to the fact that some RPMs
  72.  * change the variable during installation
  73.  * list member is a map with keys "operation" (value "add" or "detete") and
  74.  * "name" (name of the module)
  75.  */
  76. list<map<string,string> > kernel_modules_to_load = [];
  77.  
  78.  
  79. // kernel was reinstalled
  80.  
  81. /**
  82.  *  A flag to indicate if a popup informing about the kernel change should
  83.  *  be displayed by inst_suseconfig.
  84.  */
  85. boolean inform_about_kernel_change = false;
  86.  
  87. // other variables
  88.  
  89. /**
  90.  * fallback map for kernel
  91.  */
  92. map<string, string> fallbacks = $[
  93.     "kernel-bigsmp" : "kernel-smp",
  94.     "kernel-smp": "kernel-default"
  95. ];
  96.  
  97. void ParseInstallationKernelCmdline ();
  98.  
  99.  
  100.     //---------------------------------------------------------------
  101.     // local defines
  102.  
  103. /**
  104.  * Hide passwords in command line option string
  105.  * @param in input string
  106.  * @return string outpit string
  107.  */
  108. string HidePasswords(string in)
  109. {
  110.     string ret = "";
  111.  
  112.     if (in != nil)
  113.     {
  114.     list<string> parts = splitstring(in, " ");
  115.  
  116.     boolean first = true;
  117.     foreach(string p, parts, {
  118.         string cmdopt = p;
  119.         if (regexpmatch(p, "^INST_PASSWORD="))
  120.         {
  121.             cmdopt = "INST_PASSWORD=******";
  122.         }
  123.         else if (regexpmatch(p, "^FTPPASSWORD="))
  124.         {
  125.             cmdopt = "FTPPASSWORD=********";
  126.         }
  127.  
  128.         if (first)
  129.         {
  130.             first = false;
  131.         }
  132.         else
  133.         {
  134.             ret = ret + " ";
  135.         }
  136.  
  137.         ret = ret + cmdopt;
  138.         }
  139.     );
  140.     }
  141.     else
  142.     {
  143.     ret = nil;
  144.     }
  145.  
  146.     return ret;
  147. }
  148.  
  149.     /**
  150.      * AddCmdLine ()
  151.      * @param    string    name of parameter
  152.      * @param    string    args of parameter
  153.      *
  154.      * add "name=args" to kernel boot parameters
  155.      * add just "name" if args = ""
  156.      * @see: cmdLine
  157.      */
  158.     global define void AddCmdLine (string name, string arg)
  159.     {
  160.     if (! cmdline_parsed)
  161.         ParseInstallationKernelCmdline ();
  162.     cmdLine = cmdLine + " " + name;
  163.     if (arg != "")
  164.     {
  165.         cmdLine = cmdLine + "=" + arg;
  166.     }
  167.     y2milestone ("cmdLine '%1'", HidePasswords(cmdLine));
  168.     return;
  169.     }
  170.  
  171.     /**
  172.      * @param    cmdline    string
  173.      *
  174.      * @return    void
  175.      * Filters out yast2 specific boot parameters and sets
  176.      * Parameters to the important cmdline parts.
  177.      */
  178.     define void ExtractCmdlineParameters (string line)
  179.     {
  180.     // discard \n
  181.     line = deletechars (line, "\n");
  182.  
  183.     // list of parameters to be discarded (yast internals)
  184.  
  185.     list discardlist = [
  186.     ];
  187.  
  188.     list<string> cmdlist = [];
  189.  
  190.     integer parse_index = 0;
  191.     boolean in_quotes = false;
  192.     boolean after_backslash = false;
  193.     string current_param = "";
  194.     while (parse_index < size (line))
  195.     {
  196.         string current_char = substring (line, parse_index, 1);
  197.         if (current_char == "\"" && ! after_backslash)
  198.         in_quotes = ! in_quotes;
  199.         if (current_char == " " && ! in_quotes)
  200.         {
  201.         cmdlist = add (cmdlist, current_param);
  202.         current_param = "";
  203.         }
  204.         else
  205.         current_param = current_param + current_char;
  206.         if (current_char == "\\")
  207.         after_backslash = true;
  208.         else
  209.         after_backslash = false;
  210.         parse_index = parse_index + 1;
  211.     }
  212.     cmdlist = add (cmdlist, current_param);
  213.  
  214. //    this is wrong because of eg. >>o="p a r a m"<<, see bugzilla 26147
  215. //    list cmdlist = splitstring (line, " ");
  216.  
  217.     // some systems (pseries) can autodetect the serial console
  218.     if (contains (cmdlist, "AUTOCONSOLE"))
  219.     {
  220.         discardlist = add (discardlist, "console");
  221.         discardlist = add (discardlist, "AUTOCONSOLE");
  222.     }
  223.  
  224.     // backdoor to re-enable update on UL/SLES
  225.     if (contains (cmdlist, "suse_update"))
  226.     {
  227.         discardlist = add (discardlist, "suse_update");
  228.         suse_update = true;
  229.     }
  230.  
  231.     foreach (string parameter, cmdlist,
  232.     {
  233.         // split "key=value" to ["key", "value"]
  234.  
  235.         list<string> param_value_list = splitstring (parameter, "=");
  236.         string key = param_value_list[0]:"";
  237.         string value = param_value_list[1]:"";
  238.  
  239.         // now only collect keys not in discardlist
  240.         if (size (param_value_list) > 0)
  241.         {
  242.         if (!contains (discardlist, key))
  243.         {
  244.             if (param_value_list[0]:"" == "vga")
  245.             {
  246.             if (regexpmatch (value, "^(0x)?[0-9a-fA-F]+$")
  247.                 || contains (["normal", "ext", "ask"], value))
  248.             {
  249.                 vgaType = value;
  250.             }
  251.             else
  252.             {
  253.                 y2warning ("Incorrect VGA kernel parameter: %1",
  254.                 value);
  255.             }
  256.             }
  257.             else
  258.             {
  259.             AddCmdLine (key, value);
  260.             }
  261.         }
  262.         }
  263.     });
  264.  
  265.     return;
  266.     }
  267.  
  268. /**
  269.  * Parse installation kernel commad line got from install.inf
  270.  */
  271. void ParseInstallationKernelCmdline () {
  272.     cmdline_parsed = true;
  273.     if (! (Stage::initial () || Stage::cont ()))
  274.     return;
  275.     string tmp = (string) SCR::Read (.etc.install_inf.Cmdline);
  276.  
  277.     y2milestone ("cmdline from install.inf is: %1", HidePasswords(tmp));
  278.     if (tmp != nil) {
  279.     // extract extra boot parameters given in installation
  280.     ExtractCmdlineParameters (tmp);
  281.     }
  282. }
  283.  
  284. /**
  285.  * Get the vga= kernel parameter
  286.  * @return string the vga= kernel parameter
  287.  */
  288. global string GetVgaType () {
  289.     if (! cmdline_parsed)
  290.     ParseInstallationKernelCmdline ();
  291.     return vgaType;
  292. }
  293.  
  294. /**
  295.  * Set the vga= kernel argument
  296.  * FIXME is heer because of bootloader module, should be removed
  297.  */
  298. global void SetVgaType (string new_vga) {
  299.     if (! cmdline_parsed)
  300.     ParseInstallationKernelCmdline ();
  301.     vgaType = new_vga;
  302. }
  303.  
  304. /**
  305.  * Check if suse_update kernel command line argument was passed
  306.  * @return boolean true if it was
  307.  */
  308. global boolean GetSuSEUpdate () {
  309.     if (! cmdline_parsed)
  310.     ParseInstallationKernelCmdline ();
  311.     return suse_update;
  312. }
  313.  
  314. /**
  315.  * Get the kernel command line
  316.  * @return string the command line
  317.  */
  318. global string GetCmdLine () {
  319.     if (! cmdline_parsed)
  320.     ParseInstallationKernelCmdline ();
  321.     return cmdLine;
  322. }
  323.  
  324. /**
  325.  * Set the kernel command line
  326.  * FIXME is heer because of bootloader module, should be removed
  327.  */
  328. global void SetCmdLine (string new_cmd_line) {
  329.     if (! cmdline_parsed)
  330.     ParseInstallationKernelCmdline ();
  331.     cmdLine = new_cmd_line;
  332. }
  333.  
  334.  
  335.  
  336.     //---------------------------------------------------------------
  337.  
  338.     /**
  339.      * select kernel depending on architecture and system type.
  340.      *
  341.      * @return void
  342.      */
  343.     global define void ProbeKernel ()
  344.     {
  345.     kernel_packages = ["kernel-default"];
  346.  
  347.     if (Arch::is_uml ())
  348.     {
  349.         y2milestone ("ProbeKernel: UML");
  350.         kernel_packages = ["kernel-um"];
  351.     }
  352.     else if (Arch::is_xen ())
  353.     {
  354.         y2milestone ("ProbeKernel: XEN");
  355.  
  356.         // use xenpae kernel package if xenpae kernel is currently running
  357.         boolean xenpae = false;
  358.  
  359.         map output = (map)SCR::Execute(.target.bash_output, "uname -r");
  360.         if (output["exit"]:-1 == 0 && issubstring(output["stdout"]:"", "xenpae"))
  361.         {
  362.         xenpae = true;
  363.         y2milestone("Running Xen PAE kernel detected");
  364.         }
  365.  
  366.         kernel_packages = (xenpae) ? ["kernel-xenpae"] : ["kernel-xen"];
  367.     }
  368.     else if (Arch::i386 ())
  369.     {
  370.         // get flags from WFM /proc/cpuinfo (for pae and tsc tests below)
  371.  
  372.         string cpuinfo_flags = (string) SCR::Read(.proc.cpuinfo.value."0"."flags");    // check only first processor
  373.         list cpuflags = (size(cpuinfo_flags) > 0) ? splitstring(cpuinfo_flags, " ") : [];
  374.  
  375.         // check for "roughly" >= 4GB memory (see bug #40729)
  376.         list memories = (list) SCR::Read(.probe.memory);
  377.         integer memsize = memories[0,"resource","phys_mem",0,"range"]:0;
  378.         integer fourGB = 0x0C0000000;
  379.         y2milestone ("Physical memory %1", memsize);
  380.  
  381.         // for memory > 4GB and PAE support we install kernel-bigsmp,
  382.         // regardles of SMP or not.
  383.         if (memsize >= fourGB && contains (cpuflags, "pae"))
  384.         {
  385.         y2milestone ("Kernel switch: mem >= 4GB && PAE");
  386.         kernel_packages = ["kernel-bigsmp"];
  387.         }
  388.     }
  389.     else if (Arch::ppc ())
  390.     {
  391.         binary = "vmlinux";
  392.  
  393.         if (Arch::board_iseries ())
  394.         {
  395.         kernel_packages = ["kernel-iseries64"];
  396.         }
  397.         else if (Arch::ppc32 ())
  398.         {
  399.         kernel_packages = ["kernel-default"];
  400.         }
  401.         else
  402.         {
  403.         kernel_packages = ["kernel-ppc64"];
  404.         }
  405.     }
  406.     else if (Arch::ia64 ())
  407.     {
  408.         kernel_packages = ["kernel-default"];
  409.     }
  410.     else if (Arch::s390 ())
  411.     {
  412.         kernel_packages = ["kernel-default"];
  413.         binary   = "image";
  414.     }
  415.  
  416.     kernel_probed = true;
  417.     y2milestone("ProbeKernel determined: %1", kernel_packages);
  418.  
  419.     }  // ProbeKernel ()
  420.  
  421. /*
  422.  * Set a custom kernel.
  423.  * @param custom_kernels a list of kernel packages
  424.  */
  425. global define void SetPackages (list<string> custom_kernels) {
  426.     // probe to avoid later probing
  427.     if (! kernel_probed)
  428.     {
  429.     ProbeKernel ();
  430.     }
  431.     kernel_packages = custom_kernels;
  432. }
  433.  
  434.  
  435. // functinos related to kernel packages
  436.  
  437. /**
  438.  * Het the name of kernel binary under /boot
  439.  * @return string the name of the kernel binary
  440.  */
  441. global string GetBinary () {
  442.     if (! kernel_probed)
  443.     {
  444.     ProbeKernel ();
  445.     }
  446.     return binary;
  447. }
  448.  
  449. /**
  450.  * Get the list of kernel packages
  451.  * @return a list of kernel packages
  452.  */
  453. global list<string> GetPackages () {
  454.     if (! kernel_probed)
  455.     {
  456.     ProbeKernel ();
  457.     }
  458.     return kernel_packages;
  459. }
  460.  
  461. /**
  462.  * Compute kernel package
  463.  * @return string selected kernel
  464.  */
  465. global string ComputePackage () {
  466.     list<string> packages = GetPackages ();
  467.     string the_kernel = packages[0]:"";
  468.     y2milestone ("Selecting '%1' as kernel package", the_kernel);
  469.     while (the_kernel != ""
  470.        && !Pkg::IsAvailable (the_kernel))
  471.     {
  472.     the_kernel = fallbacks[the_kernel]:"";
  473.     y2milestone ("Not available, falling back to '%1'", the_kernel);
  474.     }
  475.  
  476.     if (the_kernel != "")
  477.     {
  478.     final_kernel = the_kernel;
  479.     }
  480.     else
  481.     {
  482.     y2warning ("%1 not available, using kernel-default",
  483.            kernel_packages);
  484.  
  485.     final_kernel = "kernel-default";
  486.     }
  487.     return final_kernel;
  488. }
  489.  
  490. global string GetFinalKernel () {
  491.     if (final_kernel == nil)
  492.     {
  493.     ComputePackage ();
  494.     }
  495.     return final_kernel;
  496. }
  497.  
  498. /**
  499.  * Compute kernel package for the specified base kernel package
  500.  * @param base string the base kernel package name (eg. kernel-default)
  501.  * @param check_avail boolean if true, additional packages are checked for
  502.  *  for being available on the medias before adding to the list
  503.  * @return a list of all kernel packages (including the base package) that
  504.  *  are to be installed together with the base package
  505.  */
  506. global list<string> ComputePackagesForBase (string base, boolean check_avail) {
  507.     // Note: kernel-*-nongpl packages have been dropped, use base only
  508.     list<string> ret = [ base ];
  509.     y2milestone ("Packages for base %1: %2", base, ret);
  510.     return ret;
  511. }
  512.  
  513. /**
  514.  * Compute kernel packages
  515.  * @return list of selected kernel packages
  516.  */
  517. global list <string> ComputePackages () {
  518.     string kernel = ComputePackage ();
  519.     return ComputePackagesForBase (kernel, true);
  520. }
  521.  
  522. // functions related to kernel's modules loaded on boot
  523.  
  524. /**
  525.  * Add a kernel module to the list of modules to load after boot
  526.  * @param string module name
  527.  * add the module name to sysconfig variable
  528.  */
  529. global void AddModuleToLoad (string name) {
  530.     y2milestone ("Adding module to be loaded at boot: %1", name);
  531.     kernel_modules_to_load = add (kernel_modules_to_load, $[
  532.     "operation" : "add",
  533.     "name" : name,
  534.     ]);
  535. }
  536.  
  537. /**
  538.  * Remove a kernel module from the list of modules to load after boot
  539.  * @param name string the name of the module
  540.  */
  541. global void RemoveModuleToLoad (string name) {
  542.     y2milestone ("Removing module to be loaded at boot: %1", name);
  543.     kernel_modules_to_load = add (kernel_modules_to_load, $[
  544.     "operation" : "remove",
  545.     "name" : name,
  546.     ]);
  547. }
  548.  
  549. /**
  550.  * SaveModuleToLoad ()
  551.  * save the sysconfig variable to the file
  552.  * @return boolean true on success
  553.  */
  554. global boolean SaveModulesToLoad () {
  555.     // if nothing changed, just return success
  556.     if (size (kernel_modules_to_load) == 0)
  557.     return true;
  558.  
  559.     // first read current status
  560.     string modules_to_load_str = (string)
  561.     SCR::Read (.sysconfig.kernel.MODULES_LOADED_ON_BOOT);
  562.     if (modules_to_load_str == nil)
  563.     modules_to_load_str = "";
  564.     list<string> modules_to_load = splitstring (modules_to_load_str, " ");
  565.     modules_to_load = filter (string s, modules_to_load, {return s != "";});
  566.     y2milestone ("Read modules to be loaded at boot: %1", modules_to_load);
  567.  
  568.     // apply operations on the list
  569.     foreach (map<string,string> op_desc, kernel_modules_to_load, {
  570.     string op = op_desc["operation"]:"";
  571.     string name = op_desc["name"]:"";
  572.     if (op == "remove")
  573.     {
  574.         modules_to_load = filter (string m, modules_to_load, {
  575.         return m != name;
  576.         });
  577.     }
  578.     else if (op == "add")
  579.     {
  580.         if (! contains (modules_to_load, name))
  581.         modules_to_load = add (modules_to_load, name);
  582.     }
  583.     });
  584.  
  585.     // and sabe the list
  586.     y2milestone ("Saving modules to be loaded at boot: %1", modules_to_load);
  587.     modules_to_load_str = mergestring (modules_to_load, " ");
  588.     SCR::Write (.sysconfig.kernel.MODULES_LOADED_ON_BOOT, modules_to_load_str);
  589.     return (boolean)SCR::Write (.sysconfig.kernel, nil);
  590. }
  591.  
  592. // kernel was reinstalled stuff
  593.  
  594. /**
  595.  *  Set inform_about_kernel_change.
  596.  */
  597. global define void SetInformAboutKernelChange (boolean b)
  598. {
  599.     inform_about_kernel_change = b;
  600. }
  601.  
  602. /**
  603.  *  Get inform_about_kernel_change.
  604.  */
  605. global define boolean GetInformAboutKernelChange ()
  606. {
  607.     return inform_about_kernel_change;
  608. }
  609.  
  610.  
  611.  
  612. /* EOF */
  613. }
  614.