Index: uspace/lib/device/include/hr.h
===================================================================
--- uspace/lib/device/include/hr.h	(revision dfa23139b238a19fdf1f2f5cb9a5e43a78b00d7e)
+++ uspace/lib/device/include/hr.h	(revision f81960c5dd5ffc19dec3d22be6176802972b2639)
@@ -43,4 +43,5 @@
 /* for now */
 #define HR_MAX_EXTENTS 4
+#define HR_MAX_HOTSPARES HR_MAX_EXTENTS
 
 #define HR_DEVNAME_LEN 32
@@ -57,5 +58,6 @@
 	HR_VOL_ONLINE,	/* OK, OPTIMAL */
 	HR_VOL_FAULTY,
-	HR_VOL_DEGRADED /* also used for partial, but usable mirror */
+	HR_VOL_DEGRADED, /* also used for partial, but usable mirror */
+	HR_VOL_REBUILD
 } hr_vol_status_t;
 
@@ -63,5 +65,7 @@
 	HR_EXT_ONLINE,	/* OK */
 	HR_EXT_MISSING,
-	HR_EXT_FAILED
+	HR_EXT_FAILED,
+	HR_EXT_REBUILD,
+	HR_EXT_HOTSPARE
 } hr_ext_status_t;
 
@@ -84,5 +88,7 @@
 typedef struct hr_vol_info {
 	hr_extent_t extents[HR_MAX_EXTENTS];
+	hr_extent_t hotspares[HR_MAX_HOTSPARES];
 	size_t extent_no;
+	size_t hotspare_no;
 	service_id_t svc_id;
 	hr_level_t level;
@@ -98,4 +104,5 @@
 extern errno_t hr_create(hr_t *, hr_config_t *, bool);
 extern errno_t hr_stop(const char *, long);
+extern errno_t hr_add_hotspare(service_id_t, service_id_t);
 extern errno_t hr_print_status(void);
 
Index: uspace/lib/device/include/ipc/hr.h
===================================================================
--- uspace/lib/device/include/ipc/hr.h	(revision dfa23139b238a19fdf1f2f5cb9a5e43a78b00d7e)
+++ uspace/lib/device/include/ipc/hr.h	(revision f81960c5dd5ffc19dec3d22be6176802972b2639)
@@ -42,4 +42,5 @@
 	HR_ASSEMBLE,
 	HR_STOP,
+	HR_ADD_HOTSPARE,
 	HR_STATUS
 } hr_request_t;
Index: uspace/lib/device/src/hr.c
===================================================================
--- uspace/lib/device/src/hr.c	(revision dfa23139b238a19fdf1f2f5cb9a5e43a78b00d7e)
+++ uspace/lib/device/src/hr.c	(revision f81960c5dd5ffc19dec3d22be6176802972b2639)
@@ -166,4 +166,22 @@
 			printf("          %s    %zu       %s\n", hr_get_ext_status_msg(ext->status), i, devname);
 	}
+
+	if (vol_info->hotspare_no == 0)
+		return EOK;
+
+	printf("hotspares: [status] [index] [devname]\n");
+	for (i = 0; i < vol_info->hotspare_no; i++) {
+		ext = &vol_info->hotspares[i];
+		if (ext->status == HR_EXT_MISSING) {
+			devname = (char *) "MISSING-devname";
+		} else {
+			rc = loc_service_get_name(ext->svc_id, &devname);
+			if (rc != EOK)
+				return rc;
+		}
+		printf("            %s   %zu     %s\n",
+		    hr_get_ext_status_msg(ext->status), i, devname);
+	}
+
 	return EOK;
 }
@@ -194,4 +212,27 @@
 	if (rc != EOK)
 		goto error;
+error:
+	hr_sess_destroy(hr);
+	return rc;
+}
+
+errno_t hr_add_hotspare(service_id_t vol_svc_id, service_id_t hs_svc_id)
+{
+	hr_t *hr;
+	errno_t rc;
+	async_exch_t *exch;
+
+	rc = hr_sess_init(&hr);
+	if (rc != EOK)
+		return rc;
+
+	exch = async_exchange_begin(hr->sess);
+	if (exch == NULL) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	rc = async_req_2_0(exch, HR_ADD_HOTSPARE, vol_svc_id, hs_svc_id);
+	async_exchange_end(exch);
 error:
 	hr_sess_destroy(hr);
@@ -277,4 +318,6 @@
 	case HR_VOL_DEGRADED:
 		return "DEGRADED";
+	case HR_VOL_REBUILD:
+		return "REBUILD";
 	default:
 		return "UNKNOWN";
@@ -291,4 +334,8 @@
 	case HR_EXT_FAILED:
 		return "FAILED";
+	case HR_EXT_REBUILD:
+		return "REBUILD";
+	case HR_EXT_HOTSPARE:
+		return "HOTSPARE";
 	default:
 		return "UNKNOWN";
