Revision 323f9095

b/lib/backend.py
1086 1086
  return block_devices
1087 1087

  
1088 1088

  
1089
def StartInstance(instance):
1089
def StartInstance(instance, startup_paused):
1090 1090
  """Start an instance.
1091 1091

  
1092 1092
  @type instance: L{objects.Instance}
1093 1093
  @param instance: the instance object
1094
  @type startup_paused: bool
1095
  @param instance: pause instance at startup?
1094 1096
  @rtype: None
1095 1097

  
1096 1098
  """
......
1103 1105
  try:
1104 1106
    block_devices = _GatherAndLinkBlockDevs(instance)
1105 1107
    hyper = hypervisor.GetHypervisor(instance.hypervisor)
1106
    hyper.StartInstance(instance, block_devices)
1108
    hyper.StartInstance(instance, block_devices, startup_paused)
1107 1109
  except errors.BlockDeviceError, err:
1108 1110
    _Fail("Block device error: %s", err, exc=True)
1109 1111
  except errors.HypervisorError, err:
b/lib/cli.py
162 162
  "SRC_DIR_OPT",
163 163
  "SRC_NODE_OPT",
164 164
  "SUBMIT_OPT",
165
  "STARTUP_PAUSED_OPT",
165 166
  "STATIC_OPT",
166 167
  "SYNC_OPT",
167 168
  "TAG_ADD_OPT",
......
1223 1224
                                     " disk templates, e.g. %s)" %
1224 1225
                                     utils.CommaJoin(constants.DTS_INT_MIRROR))
1225 1226

  
1227
STARTUP_PAUSED_OPT = cli_option("--paused", dest="startup_paused",
1228
                                action="store_true", default=False,
1229
                                help="Pause instance at startup")
1230

  
1226 1231

  
1227 1232
#: Options provided by all commands
1228 1233
COMMON_OPTS = [DEBUG_OPT]
b/lib/client/gnt_instance.py
662 662
  op = opcodes.OpInstanceStartup(instance_name=name,
663 663
                                 force=opts.force,
664 664
                                 ignore_offline_nodes=opts.ignore_offline,
665
                                 no_remember=opts.no_remember)
665
                                 no_remember=opts.no_remember,
666
                                 startup_paused=opts.startup_paused)
666 667
  # do not add these parameters to the opcode unless they're defined
667 668
  if opts.hvparams:
668 669
    op.hvparams = opts.hvparams
......
1453 1454
     m_node_tags_opt, m_pri_node_tags_opt, m_sec_node_tags_opt,
1454 1455
     m_inst_tags_opt, m_clust_opt, m_inst_opt, SUBMIT_OPT, HVOPTS_OPT,
1455 1456
     BACKEND_OPT, DRY_RUN_OPT, PRIORITY_OPT, IGNORE_OFFLINE_OPT,
1456
     NO_REMEMBER_OPT],
1457
     NO_REMEMBER_OPT, STARTUP_PAUSED_OPT],
1457 1458
    "<instance>", "Starts an instance"),
1458 1459
  'reboot': (
1459 1460
    GenericManyOps("reboot", _RebootInstance), [ArgInstance()],
b/lib/cmdlib.py
5705 5705
      _StartInstanceDisks(self, instance, force)
5706 5706

  
5707 5707
      result = self.rpc.call_instance_start(node_current, instance,
5708
                                            self.op.hvparams, self.op.beparams)
5708
                                            self.op.hvparams, self.op.beparams,
5709
                                            self.op.startup_paused)
5709 5710
      msg = result.fail_msg
5710 5711
      if msg:
5711 5712
        _ShutdownInstanceDisks(self, instance)
......
5795 5796
        self.LogInfo("Instance %s was already stopped, starting now",
5796 5797
                     instance.name)
5797 5798
      _StartInstanceDisks(self, instance, ignore_secondaries)
5798
      result = self.rpc.call_instance_start(node_current, instance, None, None)
5799
      result = self.rpc.call_instance_start(node_current, instance,
5800
                                            None, None, False)
5799 5801
      msg = result.fail_msg
5800 5802
      if msg:
5801 5803
        _ShutdownInstanceDisks(self, instance)
......
6646 6648
        _ShutdownInstanceDisks(self, instance)
6647 6649
        raise errors.OpExecError("Can't activate the instance's disks")
6648 6650

  
6649
      result = self.rpc.call_instance_start(target_node, instance, None, None)
6651
      result = self.rpc.call_instance_start(target_node, instance,
6652
                                            None, None, False)
6650 6653
      msg = result.fail_msg
6651 6654
      if msg:
6652 6655
        _ShutdownInstanceDisks(self, instance)
......
8771 8774
      self.cfg.Update(iobj, feedback_fn)
8772 8775
      logging.info("Starting instance %s on node %s", instance, pnode_name)
8773 8776
      feedback_fn("* starting instance...")
8774
      result = self.rpc.call_instance_start(pnode_name, iobj, None, None)
8777
      result = self.rpc.call_instance_start(pnode_name, iobj,
8778
                                            None, None, False)
8775 8779
      result.Raise("Could not start instance")
8776 8780

  
8777 8781
    return list(iobj.all_nodes)
......
11190 11194
            not self.op.remove_instance):
11191 11195
          assert not activate_disks
11192 11196
          feedback_fn("Starting instance %s" % instance.name)
11193
          result = self.rpc.call_instance_start(src_node, instance, None, None)
11197
          result = self.rpc.call_instance_start(src_node, instance,
11198
                                                None, None, False)
11194 11199
          msg = result.fail_msg
11195 11200
          if msg:
11196 11201
            feedback_fn("Failed to start instance: %s" % msg)
b/lib/hypervisor/hv_base.py
134 134
  def __init__(self):
135 135
    pass
136 136

  
137
  def StartInstance(self, instance, block_devices):
137
  def StartInstance(self, instance, block_devices, startup_paused):
138 138
    """Start an instance."""
139 139
    raise NotImplementedError
140 140

  
b/lib/hypervisor/hv_chroot.py
135 135
        data.append((file_name, 0, 0, 0, 0, 0))
136 136
    return data
137 137

  
138
  def StartInstance(self, instance, block_devices):
138
  def StartInstance(self, instance, block_devices, startup_paused):
139 139
    """Start an instance.
140 140

  
141 141
    For the chroot manager, we try to mount the block device and
b/lib/hypervisor/hv_fake.py
147 147
    file_name = self._InstanceFile(instance_name)
148 148
    utils.RemoveFile(file_name)
149 149

  
150
  def StartInstance(self, instance, block_devices):
150
  def StartInstance(self, instance, block_devices, startup_paused):
151 151
    """Start an instance.
152 152

  
153 153
    For the fake hypervisor, it just creates a file in the base dir,
b/lib/hypervisor/hv_kvm.py
502 502
        data.append(info)
503 503
    return data
504 504

  
505
  def _GenerateKVMRuntime(self, instance, block_devices):
505
  def _GenerateKVMRuntime(self, instance, block_devices, startup_paused):
506 506
    """Generate KVM information to start an instance.
507 507

  
508 508
    """
......
523 523
    kvm_cmd.extend(['-daemonize'])
524 524
    if not instance.hvparams[constants.HV_ACPI]:
525 525
      kvm_cmd.extend(['-no-acpi'])
526
    if startup_paused:
527
      kvm_cmd.extend(['-S'])
526 528

  
527 529
    hvp = instance.hvparams
528 530
    boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK
......
901 903
    for filename in temp_files:
902 904
      utils.RemoveFile(filename)
903 905

  
904
  def StartInstance(self, instance, block_devices):
906
  def StartInstance(self, instance, block_devices, startup_paused):
905 907
    """Start an instance.
906 908

  
907 909
    """
908 910
    self._CheckDown(instance.name)
909
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices)
911
    kvm_runtime = self._GenerateKVMRuntime(instance, block_devices, startup_paused)
910 912
    self._SaveKVMRuntime(instance, kvm_runtime)
911 913
    self._ExecuteKVMRuntime(instance, kvm_runtime)
912 914

  
b/lib/hypervisor/hv_lxc.py
266 266

  
267 267
    return "\n".join(out) + "\n"
268 268

  
269
  def StartInstance(self, instance, block_devices):
269
  def StartInstance(self, instance, block_devices, startup_paused):
270 270
    """Start an instance.
271 271

  
272 272
    For LCX, we try to mount the block device and execute 'lxc-start'.
b/lib/hypervisor/hv_xen.py
180 180
    xm_list = self._GetXMList(False)
181 181
    return xm_list
182 182

  
183
  def StartInstance(self, instance, block_devices):
183
  def StartInstance(self, instance, block_devices, startup_paused):
184 184
    """Start an instance.
185 185

  
186 186
    """
187 187
    self._WriteConfigFile(instance, block_devices)
188
    result = utils.RunCmd(["xm", "create", instance.name])
188
    cmd = ["xm", "create"]
189
    if startup_paused:
190
      cmd.extend(["--paused"])
191
    cmd.extend([instance.name])
192
    result = utils.RunCmd(cmd)
189 193

  
190 194
    if result.failed:
191 195
      raise errors.HypervisorError("Failed to start instance %s: %s (%s)" %
b/lib/opcodes.py
125 125
_PMigrationTargetNode = ("target_node", None, ht.TMaybeString,
126 126
                         "Target node for shared-storage instances")
127 127

  
128
_PStartupPaused = ("startup_paused", False, ht.TBool,
129
                   "Pause instance at startup")
130

  
131

  
128 132
#: OP_ID conversion regular expression
129 133
_OPID_RE = re.compile("([a-z])([A-Z])")
130 134

  
......
1018 1022
     "Temporary hypervisor parameters, hypervisor-dependent"),
1019 1023
    ("beparams", ht.EmptyDict, ht.TDict, "Temporary backend parameters"),
1020 1024
    _PNoRemember,
1025
    _PStartupPaused,
1021 1026
    ]
1022 1027

  
1023 1028

  
b/lib/rpc.py
661 661
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
662 662

  
663 663
  @_RpcTimeout(_TMO_NORMAL)
664
  def call_instance_start(self, node, instance, hvp, bep):
664
  def call_instance_start(self, node, instance, hvp, bep, startup_paused):
665 665
    """Starts an instance.
666 666

  
667 667
    This is a single-node call.
668 668

  
669 669
    """
670 670
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
671
    return self._SingleNodeCall(node, "instance_start", [idict])
671
    return self._SingleNodeCall(node, "instance_start", [idict, startup_paused])
672 672

  
673 673
  @_RpcTimeout(_TMO_NORMAL)
674 674
  def call_instance_shutdown(self, node, instance, timeout):
b/lib/server/noded.py
557 557
    """Start an instance.
558 558

  
559 559
    """
560
    instance = objects.Instance.FromDict(params[0])
561
    return backend.StartInstance(instance)
560
    (instance_name, startup_paused) = params
561
    instance = objects.Instance.FromDict(instance_name)
562
    return backend.StartInstance(instance, startup_paused)
562 563

  
563 564
  @staticmethod
564 565
  def perspective_migration_info(params):
b/man/gnt-instance.rst
848 848
| --tags \| --node-tags \| --pri-node-tags \| --sec-node-tags]
849 849
| [{-H|--hypervisor-parameters} ``key=value...``]
850 850
| [{-B|--backend-parameters} ``key=value...``]
851
| [--submit]
851
| [--submit] [--paused]
852 852
| {*name*...}
853 853

  
854 854
Starts one or more instances, depending on the following options.  The
......
889 889
    will start all instances in the cluster on secondary nodes with the
890 890
    tags given as arguments
891 891

  
892

  
893 892
Note that although you can pass more than one selection option, the
894 893
last one wins, so in order to guarantee the desired result, don't pass
895 894
more than one such option.
......
927 926
completion. The job ID will be shown so that it can be examined via
928 927
**gnt-job info**.
929 928

  
929
The ``--paused`` option is only valid for Xen and kvm hypervisors.  This
930
pauses the instance at the start of bootup, awaiting ``gnt-instance
931
console`` to unpause it, allowing the entire boot process to be
932
monitored for debugging.
933

  
930 934
Example::
931 935

  
932 936
    # gnt-instance start instance1.example.com
......
1039 1043
HVM instance, use a VNC client with the connection info from the
1040 1044
**info** command.
1041 1045

  
1046
For Xen/kvm instances, if the instance is paused, this attempts to
1047
unpause the instance after waiting a few seconds for the connection to
1048
the console to be made.
1049

  
1042 1050
Example::
1043 1051

  
1044 1052
    # gnt-instance console instance1.example.com

Also available in: Unified diff