commit 07813a9efd0baac14437ebcc9841c66e3131a265
Author: Iustin Pop <iustin@google.com>
Date:   Tue Feb 24 15:25:37 2009 +0000

    Remove the extra_args parameter in instance start
    
    This patch removes the extra_args parameter and instead switches the
    instance to the HV_KERNEL_ARGS hypervisor option.
    
    This is a big change, but it's a needed cleanup, this extra parameter on
    all RPC calls is not generic and we also need to have a persistent value
    here.
    
    Reviewed-by: imsnah

diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index bfba392..a3dd4eb 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -400,8 +400,7 @@ class NodeHttpServer(http.server.HttpServer):
 
     """
     instance = objects.Instance.FromDict(params[0])
-    extra_args = params[1]
-    return backend.StartInstance(instance, extra_args)
+    return backend.StartInstance(instance)
 
   @staticmethod
   def perspective_migration_info(params):
@@ -445,8 +444,7 @@ class NodeHttpServer(http.server.HttpServer):
     """
     instance = objects.Instance.FromDict(params[0])
     reboot_type = params[1]
-    extra_args = params[2]
-    return backend.InstanceReboot(instance, reboot_type, extra_args)
+    return backend.InstanceReboot(instance, reboot_type)
 
   @staticmethod
   def perspective_instance_info(params):
diff --git a/daemons/ganeti-watcher b/daemons/ganeti-watcher
index f12cab5..12bafce 100755
--- a/daemons/ganeti-watcher
+++ b/daemons/ganeti-watcher
@@ -214,9 +214,7 @@ class Instance(object):
     """Encapsulates the start of an instance.
 
     """
-    op = opcodes.OpStartupInstance(instance_name=self.name,
-                                   force=False,
-                                   extra_args=None)
+    op = opcodes.OpStartupInstance(instance_name=self.name, force=False)
     cli.SubmitOpCode(op, cl=client)
 
   def ActivateDisks(self):
diff --git a/lib/backend.py b/lib/backend.py
index 830607e..831f36c 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -856,7 +856,7 @@ def _GatherAndLinkBlockDevs(instance):
   return block_devices
 
 
-def StartInstance(instance, extra_args):
+def StartInstance(instance):
   """Start an instance.
 
   @type instance: L{objects.Instance}
@@ -873,7 +873,7 @@ def StartInstance(instance, extra_args):
   try:
     block_devices = _GatherAndLinkBlockDevs(instance)
     hyper = hypervisor.GetHypervisor(instance.hypervisor)
-    hyper.StartInstance(instance, block_devices, extra_args)
+    hyper.StartInstance(instance, block_devices)
   except errors.BlockDeviceError, err:
     logging.exception("Failed to start instance")
     return (False, "Block device error: %s" % str(err))
@@ -941,7 +941,7 @@ def InstanceShutdown(instance):
   return (True, "Instance has been shutdown successfully")
 
 
-def InstanceReboot(instance, reboot_type, extra_args):
+def InstanceReboot(instance, reboot_type):
   """Reboot an instance.
 
   @type instance: L{objects.Instance}
@@ -980,7 +980,7 @@ def InstanceReboot(instance, reboot_type, extra_args):
       stop_result = InstanceShutdown(instance)
       if not stop_result[0]:
         return stop_result
-      return StartInstance(instance, extra_args)
+      return StartInstance(instance)
     except errors.HypervisorError, err:
       msg = "Failed to hard reboot instance %s: %s" % (instance.name, err)
       logging.error(msg)
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 6ea1794..5b3b955 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2720,7 +2720,6 @@ class LUStartupInstance(LogicalUnit):
     """
     instance = self.instance
     force = self.op.force
-    extra_args = getattr(self.op, "extra_args", "")
 
     self.cfg.MarkInstanceUp(instance.name)
 
@@ -2728,7 +2727,7 @@ class LUStartupInstance(LogicalUnit):
 
     _StartInstanceDisks(self, instance, force)
 
-    result = self.rpc.call_instance_start(node_current, instance, extra_args)
+    result = self.rpc.call_instance_start(node_current, instance)
     msg = result.RemoteFailMsg()
     if msg:
       _ShutdownInstanceDisks(self, instance)
@@ -2789,7 +2788,6 @@ class LURebootInstance(LogicalUnit):
     instance = self.instance
     ignore_secondaries = self.op.ignore_secondaries
     reboot_type = self.op.reboot_type
-    extra_args = getattr(self.op, "extra_args", "")
 
     node_current = instance.primary_node
 
@@ -2798,7 +2796,7 @@ class LURebootInstance(LogicalUnit):
       for disk in instance.disks:
         self.cfg.SetDiskID(disk, node_current)
       result = self.rpc.call_instance_reboot(node_current, instance,
-                                             reboot_type, extra_args)
+                                             reboot_type)
       msg = result.RemoteFailMsg()
       if msg:
         raise errors.OpExecError("Could not reboot instance: %s" % msg)
@@ -2810,7 +2808,7 @@ class LURebootInstance(LogicalUnit):
                                  " full reboot: %s" % msg)
       _ShutdownInstanceDisks(self, instance)
       _StartInstanceDisks(self, instance, ignore_secondaries)
-      result = self.rpc.call_instance_start(node_current, instance, extra_args)
+      result = self.rpc.call_instance_start(node_current, instance)
       msg = result.RemoteFailMsg()
       if msg:
         _ShutdownInstanceDisks(self, instance)
@@ -3500,7 +3498,7 @@ class LUFailoverInstance(LogicalUnit):
         raise errors.OpExecError("Can't activate the instance's disks")
 
       feedback_fn("* starting the instance on the target node")
-      result = self.rpc.call_instance_start(target_node, instance, None)
+      result = self.rpc.call_instance_start(target_node, instance)
       msg = result.RemoteFailMsg()
       if msg:
         _ShutdownInstanceDisks(self, instance)
@@ -4741,7 +4739,7 @@ class LUCreateInstance(LogicalUnit):
       self.cfg.Update(iobj)
       logging.info("Starting instance %s on node %s", instance, pnode_name)
       feedback_fn("* starting instance...")
-      result = self.rpc.call_instance_start(pnode_name, iobj, None)
+      result = self.rpc.call_instance_start(pnode_name, iobj)
       msg = result.RemoteFailMsg()
       if msg:
         raise errors.OpExecError("Could not start instance: %s" % msg)
@@ -6189,7 +6187,7 @@ class LUExportInstance(LogicalUnit):
 
     finally:
       if self.op.shutdown and instance.admin_up:
-        result = self.rpc.call_instance_start(src_node, instance, None)
+        result = self.rpc.call_instance_start(src_node, instance)
         msg = result.RemoteFailMsg()
         if msg:
           _ShutdownInstanceDisks(self, instance)
diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index 9b9b542..b094b37 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -38,7 +38,7 @@ class BaseHypervisor(object):
   def __init__(self):
     pass
 
-  def StartInstance(self, instance, block_devices, extra_args):
+  def StartInstance(self, instance, block_devices):
     """Start an instance."""
     raise NotImplementedError
 
diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py
index 7bd9f77..48e645b 100644
--- a/lib/hypervisor/hv_fake.py
+++ b/lib/hypervisor/hv_fake.py
@@ -107,7 +107,7 @@ class FakeHypervisor(hv_base.BaseHypervisor):
         raise errors.HypervisorError("Failed to list instances: %s" % err)
     return data
 
-  def StartInstance(self, instance, block_devices, extra_args):
+  def StartInstance(self, instance, block_devices):
     """Start an instance.
 
     For the fake hypervisor, it just creates a file in the base dir,
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 9e47ebc..a94aeca 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -52,6 +52,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     constants.HV_KERNEL_PATH,
     constants.HV_INITRD_PATH,
     constants.HV_ROOT_PATH,
+    constants.HV_KERNEL_ARGS,
     constants.HV_ACPI,
     constants.HV_SERIAL_CONSOLE,
     constants.HV_VNC_BIND_ADDRESS,
@@ -219,7 +220,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
 
     return data
 
-  def _GenerateKVMRuntime(self, instance, block_devices, extra_args):
+  def _GenerateKVMRuntime(self, instance, block_devices):
     """Generate KVM information to start an instance.
 
     """
@@ -281,11 +282,11 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       initrd_path = hvp[constants.HV_INITRD_PATH]
       if initrd_path:
         kvm_cmd.extend(['-initrd', initrd_path])
-      root_append = 'root=%s ro' % instance.hvparams[constants.HV_ROOT_PATH]
-      if instance.hvparams[constants.HV_SERIAL_CONSOLE]:
-        kvm_cmd.extend(['-append', 'console=ttyS0,38400 %s' % root_append])
-      else:
-        kvm_cmd.extend(['-append', root_append])
+      root_append = ['root=%s' % hvp[constants.HV_ROOT_PATH],
+                     hvp[constants.HV_KERNEL_ARGS]]
+      if hvp[constants.HV_SERIAL_CONSOLE]:
+        root_append.append('console=ttyS0,38400')
+      kvm_cmd.extend(['-append', ' '.join(root_append)])
 
     mouse_type = hvp[constants.HV_USB_MOUSE]
     if mouse_type:
@@ -435,7 +436,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     for filename in temp_files:
       utils.RemoveFile(filename)
 
-  def StartInstance(self, instance, block_devices, extra_args):
+  def StartInstance(self, instance, block_devices):
     """Start an instance.
 
     """
@@ -444,7 +445,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       raise errors.HypervisorError("Failed to start instance %s: %s" %
                                    (instance.name, "already running"))
 
-    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices, extra_args)
+    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices)
     self._SaveKVMRuntime(instance, kvm_runtime)
     self._ExecuteKVMRuntime(instance, kvm_runtime)
 
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index f404900..eccdb24 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -44,7 +44,7 @@ class XenHypervisor(hv_base.BaseHypervisor):
   """
 
   @classmethod
-  def _WriteConfigFile(cls, instance, block_devices, extra_args):
+  def _WriteConfigFile(cls, instance, block_devices):
     """Write the Xen config file for the instance.
 
     """
@@ -159,11 +159,11 @@ class XenHypervisor(hv_base.BaseHypervisor):
     xm_list = self._GetXMList(False)
     return xm_list
 
-  def StartInstance(self, instance, block_devices, extra_args):
+  def StartInstance(self, instance, block_devices):
     """Start an instance.
 
     """
-    self._WriteConfigFile(instance, block_devices, extra_args)
+    self._WriteConfigFile(instance, block_devices)
     result = utils.RunCmd(["xm", "create", instance.name])
 
     if result.failed:
@@ -386,6 +386,7 @@ class XenPvmHypervisor(XenHypervisor):
     constants.HV_KERNEL_PATH,
     constants.HV_INITRD_PATH,
     constants.HV_ROOT_PATH,
+    constants.HV_KERNEL_ARGS,
     ]
 
   @classmethod
@@ -435,7 +436,7 @@ class XenPvmHypervisor(XenHypervisor):
                                    " not a file" % initrd_path)
 
   @classmethod
-  def _WriteConfigFile(cls, instance, block_devices, extra_args):
+  def _WriteConfigFile(cls, instance, block_devices):
     """Write the Xen config file for the instance.
 
     """
@@ -470,13 +471,11 @@ class XenPvmHypervisor(XenHypervisor):
                  cls._GetConfigFileDiskData(instance.disk_template,
                                             block_devices)))
 
-    rpath = instance.hvparams[constants.HV_ROOT_PATH]
-    config.write("root = '%s ro'\n" % rpath)
+    config.write("root = '%s'\n" % hvp[constants.HV_ROOT_PATH])
     config.write("on_poweroff = 'destroy'\n")
     config.write("on_reboot = 'restart'\n")
     config.write("on_crash = 'restart'\n")
-    if extra_args:
-      config.write("extra = '%s'\n" % extra_args)
+    config.write("extra = '%s'\n" % hvp[constants.HV_KERNEL_ARGS])
     # just in case it exists
     utils.RemoveFile("/etc/xen/auto/%s" % instance.name)
     try:
@@ -563,7 +562,7 @@ class XenHvmHypervisor(XenHypervisor):
                                    iso_path)
 
   @classmethod
-  def _WriteConfigFile(cls, instance, block_devices, extra_args):
+  def _WriteConfigFile(cls, instance, block_devices):
     """Create a Xen 3.1 HVM config file.
 
     """
@@ -654,8 +653,7 @@ class XenHvmHypervisor(XenHypervisor):
     config.write("on_poweroff = 'destroy'\n")
     config.write("on_reboot = 'restart'\n")
     config.write("on_crash = 'restart'\n")
-    if extra_args:
-      config.write("extra = '%s'\n" % extra_args)
+    config.write("extra = '%s'\n" % hvp[constants.HV_KERNEL_ARGS])
     # just in case it exists
     utils.RemoveFile("/etc/xen/auto/%s" % instance.name)
     try:
diff --git a/lib/opcodes.py b/lib/opcodes.py
index ad32783..5be660b 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -382,7 +382,7 @@ class OpStartupInstance(OpCode):
   """Startup an instance."""
   OP_ID = "OP_INSTANCE_STARTUP"
   OP_DSC_FIELD = "instance_name"
-  __slots__ = ["instance_name", "force", "extra_args"]
+  __slots__ = ["instance_name", "force"]
 
 
 class OpShutdownInstance(OpCode):
@@ -396,8 +396,7 @@ class OpRebootInstance(OpCode):
   """Reboot an instance."""
   OP_ID = "OP_INSTANCE_REBOOT"
   OP_DSC_FIELD = "instance_name"
-  __slots__ = ["instance_name", "reboot_type", "extra_args",
-               "ignore_secondaries" ]
+  __slots__ = ["instance_name", "reboot_type", "ignore_secondaries" ]
 
 
 class OpReplaceDisks(OpCode):
diff --git a/lib/rpc.py b/lib/rpc.py
index 12791fe..a9669fe 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -425,14 +425,14 @@ class RpcRunner(object):
     """
     return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
 
-  def call_instance_start(self, node, instance, extra_args):
+  def call_instance_start(self, node, instance):
     """Starts an instance.
 
     This is a single-node call.
 
     """
     return self._SingleNodeCall(node, "instance_start",
-                                [self._InstDict(instance), extra_args])
+                                [self._InstDict(instance)])
 
   def call_instance_shutdown(self, node, instance):
     """Stops an instance.
@@ -515,15 +515,14 @@ class RpcRunner(object):
     return self._SingleNodeCall(node, "instance_migrate",
                                 [self._InstDict(instance), target, live])
 
-  def call_instance_reboot(self, node, instance, reboot_type, extra_args):
+  def call_instance_reboot(self, node, instance, reboot_type):
     """Reboots an instance.
 
     This is a single-node call.
 
     """
     return self._SingleNodeCall(node, "instance_reboot",
-                                [self._InstDict(instance), reboot_type,
-                                 extra_args])
+                                [self._InstDict(instance), reboot_type])
 
   def call_instance_os_add(self, node, inst):
     """Installs an OS on the given instance.
diff --git a/man/gnt-instance.sgml b/man/gnt-instance.sgml
index d50fb65..4191a44 100644
--- a/man/gnt-instance.sgml
+++ b/man/gnt-instance.sgml
@@ -428,6 +428,29 @@
             </varlistentry>
 
             <varlistentry>
+              <term>kernel_args</term>
+              <listitem>
+                <simpara>Valid for the Xen PVM and KVM hypervisors.</simpara>
+
+                <para>
+                  This options specifies extra arguments to the kernel
+                  that will be loaded.  device. This is always used
+                  for Xen PVM, while for KVM it is only used if the
+                  <option>kernel_path</option> option is also
+                  specified.
+                </para>
+
+                <para>
+                  The default setting for this value is simply
+                  <constant>"ro"</constant>, which mounts the root
+                  disk (initially) in read-only one. For example,
+                  setting this to <userinput>single</userinput> will
+                  cause the instance to start in single-user mode.
+                </para>
+              </listitem>
+            </varlistentry>
+
+            <varlistentry>
               <term>initrd_path</term>
               <listitem>
                 <simpara>Valid for the Xen PVM and KVM hypervisors.</simpara>
@@ -1265,7 +1288,6 @@ instance5: 11225
         <cmdsynopsis>
           <command>startup</command>
           <sbr>
-          <arg>--extra=<replaceable>PARAMS</replaceable></arg>
           <arg>--force</arg>
           <sbr>
           <arg>--force-multiple</arg>
@@ -1336,14 +1358,6 @@ instance5: 11225
         </para>
 
         <para>
-          The <option>--extra</option> option is used to pass
-          additional argument to the instance's kernel for this start
-          only. Currently there is no way to specify a persistent set
-          of arguments (beside the one hardcoded). Note that this may
-          not apply to all virtualization types.
-        </para>
-
-        <para>
           Use <option>--force</option> to start even if secondary disks are
           failing.
         </para>
@@ -1365,7 +1379,6 @@ instance5: 11225
           Example:
           <screen>
 # gnt-instance start instance1.example.com
-# gnt-instance start --extra single test1.example.com
 # gnt-instance start --node node1.example.com node2.example.com
 # gnt-instance start --all
           </screen>
@@ -1432,8 +1445,6 @@ instance5: 11225
         <cmdsynopsis>
           <command>reboot</command>
           <sbr>
-          <arg>--extra=<replaceable>PARAMS</replaceable></arg>
-          <sbr>
           <arg>--type=<replaceable>REBOOT-TYPE</replaceable></arg>
           <sbr>
           <arg>--ignore-secondaries</arg>
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index e2c6eca..ad7f237 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -709,8 +709,7 @@ def StartupInstance(opts, args):
   jex = cli.JobExecutor(verbose=multi_on, cl=cl)
   for name in inames:
     op = opcodes.OpStartupInstance(instance_name=name,
-                                   force=opts.force,
-                                   extra_args=opts.extra_args)
+                                   force=opts.force)
     jex.QueueJob(name, op)
   jex.WaitOrShow(not opts.submit_only)
   return 0
@@ -1457,9 +1456,6 @@ commands = {
                "<instance>", "Stops an instance"),
   'startup': (StartupInstance, ARGS_ANY,
               [DEBUG_OPT, FORCE_OPT, m_force_multi,
-               make_option("-e", "--extra", dest="extra_args",
-                           help="Extra arguments for the instance's kernel",
-                           default=None, type="string", metavar="<PARAMS>"),
                m_node_opt, m_pri_node_opt, m_sec_node_opt,
                m_clust_opt, m_inst_opt,
                SUBMIT_OPT,
@@ -1468,9 +1464,6 @@ commands = {
 
   'reboot': (RebootInstance, ARGS_ANY,
               [DEBUG_OPT, m_force_multi,
-               make_option("-e", "--extra", dest="extra_args",
-                           help="Extra arguments for the instance's kernel",
-                           default=None, type="string", metavar="<PARAMS>"),
                make_option("-t", "--type", dest="reboot_type",
                            help="Type of reboot: soft/hard/full",
                            default=constants.INSTANCE_REBOOT_HARD,
