Index: uspace/app/hrctl/hrctl.c
===================================================================
--- uspace/app/hrctl/hrctl.c	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/app/hrctl/hrctl.c	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -104,6 +104,11 @@
 	for (i = 0; i < cfg->dev_no; i++) {
 		rc = loc_service_get_id(argv[optind], &cfg->devs[i], 0);
-		if (rc != EOK) {
-			printf("hrctl: error resolving device \"%s\"\n", argv[optind]);
+		if (rc == ENOENT) {
+			printf("hrctl: no device \"%s\", marking as missing\n",
+			    argv[optind]);
+			cfg->devs[i] = 0;
+		} else if (rc != EOK) {
+			printf("hrctl: error resolving device \"%s\", aborting\n",
+			    argv[optind]);
 			return EINVAL;
 		}
@@ -190,6 +195,11 @@
 
 		rc = loc_service_get_id(extent_devname, &cfg->devs[i], 0);
-		if (rc != EOK) {
-			printf("hrctl: error resolving device \"%s\"\n",
+		if (rc == ENOENT) {
+			printf("hrctl: no device \"%s\", marking as missing\n",
+			    extent_devname);
+			cfg->devs[i] = 0;
+			rc = EOK;
+		} else if (rc != EOK) {
+			printf("hrctl: error resolving device \"%s\", aborting\n",
 			    extent_devname);
 			return EINVAL;
Index: uspace/lib/device/include/hr.h
===================================================================
--- uspace/lib/device/include/hr.h	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/lib/device/include/hr.h	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -54,4 +54,15 @@
 } hr_level_t;
 
+typedef enum hr_vol_status {
+	HR_VOL_ONLINE,	/* OK, OPTIMAL */
+	HR_VOL_FAULTY
+} hr_vol_status_t;
+
+typedef enum hr_ext_status {
+	HR_EXT_ONLINE,	/* OK */
+	HR_EXT_MISSING,
+	HR_EXT_FAILED
+} hr_ext_status_t;
+
 typedef struct hr {
 	async_sess_t *sess;
@@ -67,5 +78,5 @@
 typedef struct hr_extent {
 	service_id_t svc_id;
-	int status;
+	hr_ext_status_t status;
 } hr_extent_t;
 
@@ -78,4 +89,5 @@
 	uint32_t strip_size;
 	size_t bsize;
+	hr_vol_status_t status;
 } hr_vol_info_t;
 
@@ -87,4 +99,7 @@
 extern errno_t hr_print_status(void);
 
+extern const char *hr_get_vol_status_msg(hr_vol_status_t);
+extern const char *hr_get_ext_status_msg(hr_ext_status_t);
+
 #endif
 
Index: uspace/lib/device/src/hr.c
===================================================================
--- uspace/lib/device/src/hr.c	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/lib/device/src/hr.c	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -130,4 +130,6 @@
 	printf("devname: %s\n", devname);
 
+	printf("status: %s\n", hr_get_vol_status_msg(vol_info->status));
+
 	printf("level: %d\n", vol_info->level);
 	if (vol_info->level == HR_LVL_0 || vol_info->level == HR_LVL_4) {
@@ -150,13 +152,17 @@
 	for (i = 0; i < vol_info->extent_no; i++) {
 		ext = &vol_info->extents[i];
-		rc = loc_service_get_name(ext->svc_id, &devname);
-		if (rc != EOK)
-			return rc;
+		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;
+		}
 		if (i == 0 && vol_info->level == HR_LVL_4)
-			printf("          P   %d        %zu       %s\n", ext->status, i, devname);
+			printf("          P   %s    %zu       %s\n", hr_get_ext_status_msg(ext->status), i, devname);
 		else if (vol_info->level == HR_LVL_4)
-			printf("              %d        %zu       %s\n", ext->status, i, devname);
+			printf("              %s    %zu       %s\n", hr_get_ext_status_msg(ext->status), i, devname);
 		else
-			printf("          %d        %zu       %s\n", ext->status, i, devname);
+			printf("          %s    %zu       %s\n", hr_get_ext_status_msg(ext->status), i, devname);
 	}
 	return EOK;
@@ -262,4 +268,30 @@
 }
 
+const char *hr_get_vol_status_msg(hr_vol_status_t status)
+{
+	switch (status) {
+	case HR_VOL_ONLINE:
+		return "ONLINE";
+	case HR_VOL_FAULTY:
+		return "FAULTY";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+const char *hr_get_ext_status_msg(hr_ext_status_t status)
+{
+	switch (status) {
+	case HR_EXT_ONLINE:
+		return "ONLINE";
+	case HR_EXT_MISSING:
+		return "MISSING";
+	case HR_EXT_FAILED:
+		return "FAILED";
+	default:
+		return "UNKNOWN";
+	}
+}
+
 /** @}
  */
Index: uspace/srv/bd/hr/hr.c
===================================================================
--- uspace/srv/bd/hr/hr.c	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/srv/bd/hr/hr.c	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -134,4 +134,18 @@
 	}
 
+	/*
+	 * If there was a missing device provided
+	 * for creation of a new array, abort
+	 */
+	if (!assemble) {
+		for (i = 0; i < cfg->dev_no; i++) {
+			if (cfg->devs[i] == 0) {
+				free(cfg);
+				async_answer_0(icall, EINVAL);
+				return;
+			}
+		}
+	}
+
 	new_volume = calloc(1, sizeof(hr_volume_t));
 	if (new_volume == NULL) {
@@ -302,4 +316,5 @@
 		info.strip_size = volume->strip_size;
 		info.bsize = volume->bsize;
+		info.status = volume->status;
 
 		if (!async_data_read_receive(&call, &size)) {
Index: uspace/srv/bd/hr/superblock.c
===================================================================
--- uspace/srv/bd/hr/superblock.c	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/srv/bd/hr/superblock.c	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -121,5 +121,4 @@
 }
 
-
 errno_t hr_fill_vol_from_meta(hr_volume_t *vol)
 {
@@ -134,10 +133,16 @@
 
 	service_id_t cfg_svc_id_order[HR_MAXDEVS] = { 0 };
-	for (size_t i = 0; i < vol->dev_no; i++)
+	for (size_t i = 0; i < vol->dev_no; i++) {
 		cfg_svc_id_order[i] = vol->extents[i].svc_id;
-
-
-	uint32_t md_order[HR_MAXDEVS] = { 0 };
+		vol->extents[i].svc_id = 0;
+		vol->extents[i].status = HR_EXT_MISSING;
+	}
+
+	int32_t md_order[HR_MAXDEVS] = { 0 };
 	for (size_t i = 0; i < vol->dev_no; i++) {
+		if (cfg_svc_id_order[i] == 0) {
+			md_order[i] = -1;
+			continue;
+		}
 		rc = read_metadata(cfg_svc_id_order[i], metadata);
 		if (rc != EOK)
@@ -149,8 +154,12 @@
 	}
 
-	for (size_t i = 0; i < vol->dev_no; i++)
-		for (size_t j = 0; j < vol->dev_no; j++)
-			if (i == md_order[j])
+	for (size_t i = 0; i < vol->dev_no; i++) {
+		for (size_t j = 0; j < vol->dev_no; j++) {
+			if (i == (uint32_t) md_order[j]) {
 				vol->extents[i].svc_id = cfg_svc_id_order[j];
+				vol->extents[i].status = HR_EXT_ONLINE;
+			}
+		}
+	}
 
 	/*
Index: uspace/srv/bd/hr/util.c
===================================================================
--- uspace/srv/bd/hr/util.c	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/srv/bd/hr/util.c	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -56,7 +56,13 @@
 
 	for (i = 0; i < vol->dev_no; i++) {
+		if (vol->extents[i].svc_id == 0) {
+			vol->extents[i].status = HR_EXT_MISSING;
+			continue;
+		}
 		rc = block_init(vol->extents[i].svc_id);
+		vol->extents[i].status = HR_EXT_ONLINE;
 		log_msg(LOG_DEFAULT, LVL_DEBUG,
-		    "hr_init_devs(): initing (%" PRIun ")", vol->extents[i].svc_id);
+		    "hr_init_devs(): initing (%" PRIun ")",
+		    vol->extents[i].svc_id);
 		if (rc != EOK) {
 			log_msg(LOG_DEFAULT, LVL_ERROR,
@@ -77,5 +83,6 @@
 
 	for (i = 0; i < vol->dev_no; i++)
-		block_fini(vol->extents[i].svc_id);
+		if (vol->extents[i].status != HR_EXT_MISSING)
+			block_fini(vol->extents[i].svc_id);
 }
 
@@ -127,13 +134,17 @@
 
 	errno_t rc;
-	size_t i, bsize, last_bsize;
-	uint64_t nblocks, last_nblocks;
+	size_t i, bsize;
+	uint64_t nblocks;
+	size_t last_bsize = 0;
+	uint64_t last_nblocks = 0;
 	uint64_t total_blocks = 0;
 
 	for (i = 0; i < vol->dev_no; i++) {
+		if (vol->extents[i].status == HR_EXT_MISSING)
+			continue;
 		rc = block_get_nblocks(vol->extents[i].svc_id, &nblocks);
 		if (rc != EOK)
 			goto error;
-		if (i != 0 && nblocks != last_nblocks) {
+		if (last_nblocks != 0 && nblocks != last_nblocks) {
 			log_msg(LOG_DEFAULT, LVL_ERROR,
 			    "number of blocks differs");
@@ -146,8 +157,10 @@
 
 	for (i = 0; i < vol->dev_no; i++) {
+		if (vol->extents[i].status == HR_EXT_MISSING)
+			continue;
 		rc = block_get_bsize(vol->extents[i].svc_id, &bsize);
 		if (rc != EOK)
 			goto error;
-		if (i != 0 && bsize != last_bsize) {
+		if (last_bsize != 0 && bsize != last_bsize) {
 			log_msg(LOG_DEFAULT, LVL_ERROR, "block sizes differ");
 			rc = EINVAL;
@@ -177,4 +190,12 @@
 }
 
+void hr_update_ext_status(hr_volume_t *vol, uint64_t extent, hr_ext_status_t s)
+{
+	log_msg(LOG_DEFAULT, LVL_WARN,
+	    "vol %s, changing extent: %lu, to status: %s",
+	    vol->devname, extent, hr_get_ext_status_msg(s));
+	vol->extents[extent].status = s;
+}
+
 /** @}
  */
Index: uspace/srv/bd/hr/util.h
===================================================================
--- uspace/srv/bd/hr/util.h	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/srv/bd/hr/util.h	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -44,7 +44,8 @@
 extern void hr_fini_devs(hr_volume_t *);
 extern errno_t hr_register_volume(hr_volume_t *);
-errno_t hr_check_devs(hr_volume_t *, uint64_t *, size_t *);
-errno_t hr_check_ba_range(hr_volume_t *, size_t, uint64_t);
-void hr_add_ba_offset(hr_volume_t *, uint64_t *);
+extern errno_t hr_check_devs(hr_volume_t *, uint64_t *, size_t *);
+extern errno_t hr_check_ba_range(hr_volume_t *, size_t, uint64_t);
+extern void hr_add_ba_offset(hr_volume_t *, uint64_t *);
+extern void hr_update_ext_status(hr_volume_t *, uint64_t, hr_ext_status_t);
 
 #endif
Index: uspace/srv/bd/hr/var.h
===================================================================
--- uspace/srv/bd/hr/var.h	(revision 066fed91b44c9a5ffe07cb5752c950d683723ca9)
+++ uspace/srv/bd/hr/var.h	(revision e47a0324928f08206491a7cd32851c858958f64f)
@@ -67,4 +67,5 @@
 	size_t dev_no;
 	hr_level_t level;
+	hr_vol_status_t status;
 } hr_volume_t;
 
