diff --git a/doc/rapi.rst b/doc/rapi.rst
index 6ec6c6d470b0618fa2b076e2060f5274db94c8ea..09fab7a15dbfe8064e836513ac2ee08a0948f57b 100644
--- a/doc/rapi.rst
+++ b/doc/rapi.rst
@@ -528,6 +528,19 @@ job id.
 
 It supports the ``force`` argument.
 
+``/2/nodes/[node_name]/storage``
+++++++++++++++++++++++++++++++++
+
+Manages storage units on the node.
+
+``GET``
+~~~~~~~
+
+Requests a list of storage units on a node. Requires the parameters
+``storage_type`` (one of ``file``, ``lvm-pv`` or ``lvm-vg``) and
+``output_fields``. The result will be a job id, using which the result can be
+retrieved.
+
 ``/2/nodes/[node_name]/tags``
 +++++++++++++++++++++++++++++
 
diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py
index 83c1f2e19da7375619dac2c41163e873f60de2e0..80c7aed4038887570e1a39a75b666377e751b5fd 100644
--- a/lib/rapi/connector.py
+++ b/lib/rapi/connector.py
@@ -159,6 +159,8 @@ CONNECTOR.update({
       rlib2.R_2_nodes_name_evacuate,
   re.compile(r'^/2/nodes/([\w\._-]+)/migrate$'):
       rlib2.R_2_nodes_name_migrate,
+  re.compile(r'^/2/nodes/([\w\._-]+)/storage$'):
+      rlib2.R_2_nodes_name_storage,
   "/2/instances": rlib2.R_2_instances,
   re.compile(r'^/2/instances/([\w\._-]+)$'): rlib2.R_2_instances_name,
   re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags,
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index 0da39c1058294afd6a11442278cf4f96923bf127..269041f2029873d915bf059e7f795e4a43da5e39 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -281,7 +281,7 @@ class R_2_nodes_name_evacuate(baserlib.R_Generic):
 
 
 class R_2_nodes_name_migrate(baserlib.R_Generic):
-  """/2/nodes/[node_name]/evacuate migrate.
+  """/2/nodes/[node_name]/migrate resource.
 
   """
   def POST(self):
@@ -296,6 +296,32 @@ class R_2_nodes_name_migrate(baserlib.R_Generic):
     return baserlib.SubmitJob([op])
 
 
+class R_2_nodes_name_storage(baserlib.R_Generic):
+  """/2/nodes/[node_name]/storage ressource.
+
+  """
+  # LUQueryNodeStorage acquires locks, hence restricting access to GET
+  GET_ACCESS = [rapi.RAPI_ACCESS_WRITE]
+
+  def GET(self):
+    node_name = self.items[0]
+
+    storage_type = self._checkStringVariable("storage_type", None)
+    if not storage_type:
+      raise http.HttpBadRequest("Missing the required 'storage_type'"
+                                " parameter")
+
+    output_fields = self._checkStringVariable("output_fields", None)
+    if not output_fields:
+      raise http.HttpBadRequest("Missing the required 'output_fields'"
+                                " parameter")
+
+    op = opcodes.OpQueryNodeStorage(nodes=[node_name],
+                                    storage_type=storage_type,
+                                    output_fields=output_fields.split(","))
+    return baserlib.SubmitJob([op])
+
+
 class R_2_instances(baserlib.R_Generic):
   """/2/instances resource.