diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index 454bc8c35360baae7b285e32cd95e553bcfb299c..12f6b7a48b35f791b33593dc72b0409486bd5b78 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -324,6 +324,16 @@ class ServerObject(pb.Avatar):
     extra_args = params[1]
     return backend.StartInstance(instance, extra_args)
 
+  @staticmethod
+  def perspective_instance_reboot(params):
+    """Reboot an instance.
+
+    """
+    instance = objects.Instance.FromDict(params[0])
+    reboot_type = params[1]
+    extra_args = params[2]
+    return backend.RebootInstance(instance, reboot_type, extra_args)
+
   @staticmethod
   def perspective_instance_info(params):
     """Query instance information.
diff --git a/lib/backend.py b/lib/backend.py
index 5df65a574eec213366e86a354b0becb48949d292..d2c154ae1b4687243df84818ddadcc4ec48dcfa4 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -585,6 +585,41 @@ def ShutdownInstance(instance):
   return True
 
 
+def RebootInstance(instance, reboot_type, extra_args):
+  """Reboot an instance.
+
+  Args:
+    instance    - name of instance to reboot
+    reboot_type - how to reboot [soft,hard,full]
+
+  """
+  running_instances = GetInstanceList()
+
+  if instance.name not in running_instances:
+    logger.Error("Cannot reboot instance that is not running")
+    return False
+
+  hyper = hypervisor.GetHypervisor()
+  if reboot_type == constants.INSTANCE_REBOOT_SOFT:
+    try:
+      hyper.RebootInstance(instance)
+    except errors.HypervisorError, err:
+      logger.Error("Failed to soft reboot instance: %s" % err)
+      return False
+  elif reboot_type == constants.INSTANCE_REBOOT_HARD:
+    try:
+      ShutdownInstance(instance)
+      StartInstance(instance, extra_args)
+    except errors.HypervisorError, err:
+      logger.Error("Failed to hard reboot instance: %s" % err)
+      return False
+  else:
+    raise errors.ParameterError("reboot_type invalid")
+
+
+  return True
+
+
 def CreateBlockDevice(disk, size, on_primary, info):
   """Creates a block device for an instance.
 
diff --git a/lib/constants.py b/lib/constants.py
index e7b33d5733f34e60eb7aecaf29e97122b47da860..d1237de90c718d2c336c04148492db8316779348 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -117,3 +117,8 @@ SSH_HOST_DSA_PRIV = SSH_CONFIG_DIR + "ssh_host_dsa_key"
 SSH_HOST_DSA_PUB = SSH_HOST_DSA_PRIV + ".pub"
 SSH_HOST_RSA_PRIV = SSH_CONFIG_DIR + "ssh_host_rsa_key"
 SSH_HOST_RSA_PUB = SSH_HOST_RSA_PRIV + ".pub"
+
+# reboot types
+INSTANCE_REBOOT_SOFT = "soft"
+INSTANCE_REBOOT_HARD = "hard"
+INSTANCE_REBOOT_FULL = "full"
diff --git a/lib/rpc.py b/lib/rpc.py
index efe847c5cc62429f8f4ac927ccddf69568e89bd1..f545e79d0432b4a43979203c31ea5e35d0f7356b 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -311,6 +311,18 @@ def call_instance_shutdown(node, instance):
   return c.getresult().get(node, False)
 
 
+def call_instance_reboot(node, instance, reboot_type, extra_args):
+  """Reboots an instance.
+
+  This is a single-node call.
+
+  """
+  c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
+  c.connect(node)
+  c.run()
+  return c.getresult().get(node, False)
+
+
 def call_instance_os_add(node, inst, osdev, swapdev):
   """Installs an OS on the given instance.