Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/app/fdisk/fdisk.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -43,4 +43,5 @@
 
 static bool quit = false;
+static fdisk_t *fdisk;
 
 /** Device menu actions */
@@ -88,5 +89,5 @@
 	}
 
-	rc = fdisk_dev_list_get(&devlist);
+	rc = fdisk_dev_list_get(fdisk, &devlist);
 	if (rc != EOK) {
 		printf("Error getting device list.\n");
@@ -207,5 +208,5 @@
 	}
 
-	for (i = FDL_CREATE_LO; i < FDL_CREATE_HI; i++) {
+	for (i = 0; i < LT_LIMIT; i++) {
 		rc = fdisk_ltype_format(i, &sltype);
 		if (rc != EOK)
@@ -229,5 +230,5 @@
 	}
 
-	rc = fdisk_label_create(dev, (fdisk_label_type_t)sel);
+	rc = fdisk_label_create(dev, (label_type_t)sel);
 	if (rc != EOK) {
 		printf("Error creating label.\n");
@@ -505,23 +506,37 @@
 	}
 
-	rc = fdisk_label_get_info(dev, &linfo);
-	if (rc != EOK) {
-		printf("Error getting label information.\n");
-		goto error;
-	}
-
-	rc = fdisk_ltype_format(linfo.ltype, &sltype);
-	if (rc != EOK) {
-		assert(rc == ENOMEM);
-		printf("Out of memory.\n");
-		goto error;
-	}
-
 	printf("Device: %s, %s\n", sdcap, svcname);
-	printf("Label type: %s\n", sltype);
-	free(sltype);
-	sltype = NULL;
 	free(sdcap);
 	sdcap = NULL;
+
+	rc = fdisk_label_get_info(dev, &linfo);
+	if (rc != EOK) {
+		printf("Error getting label information.\n");
+		goto error;
+	}
+
+	switch (linfo.dcnt) {
+	case dc_empty:
+		printf("Disk is empty.\n");
+		break;
+	case dc_label:
+		rc = fdisk_ltype_format(linfo.ltype, &sltype);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		printf("Label type: %s\n", sltype);
+		free(sltype);
+		sltype = NULL;
+		break;
+	case dc_fs:
+		printf("Disk contains a file system.\n");
+		break;
+	case dc_unknown:
+		printf("Disk contains unknown data.\n");
+		break;
+	}
 
 	part = fdisk_part_first(dev);
@@ -563,5 +578,5 @@
 	}
 
-	if (linfo.ltype != fdl_none) {
+	if (linfo.dcnt == dc_label) {
 		rc = nchoice_add(choice, "Create partition",
 		    (void *)devac_create_part);
@@ -583,5 +598,5 @@
 	}
 
-	if (linfo.ltype == fdl_none) {
+	if (linfo.dcnt == dc_empty) {
 		rc = nchoice_add(choice, "Create label",
 		    (void *)devac_create_label);
@@ -616,22 +631,14 @@
 	switch ((devac_t)sel) {
 	case devac_create_label:
-		rc = fdsk_create_label(dev);
-		if (rc != EOK)
-			goto error;
+		(void) fdsk_create_label(dev);
 		break;
 	case devac_delete_label:
-		rc = fdsk_delete_label(dev);
-		if (rc != EOK)
-			goto error;
+		(void) fdsk_delete_label(dev);
 		break;
 	case devac_create_part:
-		rc = fdsk_create_part(dev);
-		if (rc != EOK)
-			goto error;
+		(void) fdsk_create_part(dev);
 		break;
 	case devac_delete_part:
-		rc = fdsk_delete_part(dev);
-		if (rc != EOK)
-			goto error;
+		(void) fdsk_delete_part(dev);
 		break;
 	case devac_exit:
@@ -658,4 +665,10 @@
 	int rc;
 
+	rc = fdisk_create(&fdisk);
+	if (rc != EOK) {
+		printf("Error initializing Fdisk.\n");
+		return 1;
+	}
+
 	rc = fdsk_dev_sel_choice(&svcid);
 	if (rc != EOK)
@@ -665,5 +678,5 @@
 		return 0;
 
-	rc = fdisk_dev_open(svcid, &dev);
+	rc = fdisk_dev_open(fdisk, svcid, &dev);
 	if (rc != EOK) {
 		printf("Error opening device.\n");
@@ -680,4 +693,5 @@
 
 	fdisk_dev_close(dev);
+	fdisk_destroy(fdisk);
 
 	return 0;
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/lib/c/Makefile	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -153,5 +153,7 @@
 	generic/stats.c \
 	generic/assert.c \
-	generic/pio_trace.c
+	generic/pio_trace.c \
+	generic/vbd.c \
+	generic/vol.c
 
 ifeq ($(CONFIG_RTLD),y)
Index: uspace/lib/c/generic/vbd.c
===================================================================
--- uspace/lib/c/generic/vbd.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/generic/vbd.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file Virtual Block Device client API
+ */
+
+#include <errno.h>
+#include <ipc/services.h>
+#include <ipc/vbd.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <types/label.h>
+#include <vbd.h>
+
+int vbd_create(vbd_t **rvbd)
+{
+	vbd_t *vbd;
+	service_id_t vbd_svcid;
+	int rc;
+
+	vbd = calloc(1, sizeof(vbd_t));
+	if (vbd == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = loc_service_get_id(SERVICE_NAME_VBD, &vbd_svcid,
+	    IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	vbd->sess = loc_service_connect(EXCHANGE_SERIALIZE, vbd_svcid,
+	    IPC_FLAG_BLOCKING);
+	if (vbd->sess == NULL) {
+		rc = EIO;
+		goto error;
+	}
+
+	*rvbd = vbd;
+	return EOK;
+error:
+	free(vbd);
+	return rc;
+}
+
+void vbd_destroy(vbd_t *vbd)
+{
+	if (vbd == NULL)
+		return;
+
+	async_hangup(vbd->sess);
+	free(vbd);
+}
+
+int vbd_disk_add(vbd_t *vbd, service_id_t disk_sid)
+{
+	async_exch_t *exch;
+
+	exch = async_exchange_begin(vbd->sess);
+	sysarg_t rc = async_req_1_0(exch, VBD_DISK_ADD, disk_sid);
+	async_exchange_end(exch);
+
+	return (int)rc;
+}
+
+int vbd_disk_remove(vbd_t *vbd, service_id_t disk_sid)
+{
+	async_exch_t *exch;
+
+	exch = async_exchange_begin(vbd->sess);
+	sysarg_t rc = async_req_1_0(exch, VBD_DISK_REMOVE, disk_sid);
+	async_exchange_end(exch);
+
+	return (int)rc;
+}
+
+/** Get disk information. */
+int vbd_disk_info(vbd_t *vbd, service_id_t sid, vbd_disk_info_t *vinfo)
+{
+	async_exch_t *exch;
+	sysarg_t ltype;
+	int retval;
+
+	exch = async_exchange_begin(vbd->sess);
+	retval = async_req_1_1(exch, VBD_DISK_INFO, sid, &ltype);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return EIO;
+
+	vinfo->ltype = (label_type_t)ltype;
+	return EOK;
+}
+
+int vbd_label_create(vbd_t *vbd, service_id_t sid, label_type_t ltype)
+{
+	async_exch_t *exch;
+	int retval;
+
+	exch = async_exchange_begin(vbd->sess);
+	retval = async_req_2_0(exch, VBD_LABEL_CREATE, sid, ltype);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+int vbd_label_delete(vbd_t *vbd, service_id_t sid)
+{
+	async_exch_t *exch;
+	int retval;
+
+	exch = async_exchange_begin(vbd->sess);
+	retval = async_req_1_0(exch, VBD_LABEL_DELETE, sid);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/generic/vol.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file Volume service API
+ */
+
+#include <errno.h>
+#include <ipc/services.h>
+#include <ipc/vol.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <vol.h>
+
+/** Create Volume service session.
+ *
+ * @param rvol Place to store pointer to volume service session.
+ * @return     EOK on success, ENOMEM if out of memory, EIO if service
+ *             cannot be contacted.
+ */
+int vol_create(vol_t **rvol)
+{
+	vol_t *vol;
+	service_id_t vol_svcid;
+	int rc;
+
+	vol = calloc(1, sizeof(vol_t));
+	if (vol == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = loc_service_get_id(SERVICE_NAME_VOLSRV, &vol_svcid, 0);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	vol->sess = loc_service_connect(EXCHANGE_SERIALIZE, vol_svcid, 0);
+	if (vol->sess == NULL) {
+		rc = EIO;
+		goto error;
+	}
+
+	*rvol = vol;
+	return EOK;
+error:
+	free(vol);
+	return rc;
+}
+
+/** Destroy volume service session.
+ *
+ * @param vol Volume service session
+ */
+void vol_destroy(vol_t *vol)
+{
+	if (vol == NULL)
+		return;
+
+	async_hangup(vol->sess);
+	free(vol);
+}
+
+/** Get list of IDs into a buffer of fixed size.
+ *
+ * @param vol      Volume service
+ * @param method   IPC method
+ * @param arg1     First argument
+ * @param id_buf   Buffer to store IDs
+ * @param buf_size Buffer size
+ * @param act_size Place to store actual size of complete data.
+ *
+ * @return EOK on success or negative error code.
+ */
+static int vol_get_ids_once(vol_t *vol, sysarg_t method, sysarg_t arg1,
+    sysarg_t *id_buf, size_t buf_size, size_t *act_size)
+{
+	async_exch_t *exch = async_exchange_begin(vol->sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, method, arg1, &answer);
+	int rc = async_data_read_start(exch, id_buf, buf_size);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+
+	if (retval != EOK) {
+		return retval;
+	}
+
+	*act_size = IPC_GET_ARG1(answer);
+	return EOK;
+}
+
+/** Get list of IDs.
+ *
+ * Returns an allocated array of service IDs.
+ *
+ * @param vol    Volume service
+ * @param method IPC method
+ * @param arg1   IPC argument 1
+ * @param data   Place to store pointer to array of IDs
+ * @param count  Place to store number of IDs
+ * @return       EOK on success or negative error code
+ */
+static int vol_get_ids_internal(vol_t *vol, sysarg_t method, sysarg_t arg1,
+    sysarg_t **data, size_t *count)
+{
+	*data = NULL;
+	*count = 0;
+
+	size_t act_size = 0;
+	int rc = vol_get_ids_once(vol, method, arg1, NULL, 0, &act_size);
+	if (rc != EOK)
+		return rc;
+
+	size_t alloc_size = act_size;
+	service_id_t *ids = malloc(alloc_size);
+	if (ids == NULL)
+		return ENOMEM;
+
+	while (true) {
+		rc = vol_get_ids_once(vol, method, arg1, ids, alloc_size,
+		    &act_size);
+		if (rc != EOK)
+			return rc;
+
+		if (act_size <= alloc_size)
+			break;
+
+		alloc_size = act_size;
+		ids = realloc(ids, alloc_size);
+		if (ids == NULL)
+			return ENOMEM;
+	}
+
+	*count = act_size / sizeof(service_id_t);
+	*data = ids;
+	return EOK;
+}
+
+/** Get list of disks as array of service IDs.
+ *
+ * @param vol Volume service
+ * @param data Place to store pointer to array
+ * @param count Place to store length of array (number of entries)
+ *
+ * @return EOK on success or negative error code
+ */
+int vol_get_disks(vol_t *vol, service_id_t **data, size_t *count)
+{
+	return vol_get_ids_internal(vol, VOL_GET_DISKS, 0, data, count);
+}
+
+/** Get disk information. */
+int vol_disk_info(vol_t *vol, service_id_t sid, vol_disk_info_t *vinfo)
+{
+	async_exch_t *exch;
+	sysarg_t dcnt, ltype;
+	int retval;
+
+	exch = async_exchange_begin(vol->sess);
+	retval = async_req_1_2(exch, VOL_DISK_INFO, sid, &dcnt, &ltype);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return EIO;
+
+	vinfo->dcnt = (label_disk_cnt_t)dcnt;
+	vinfo->ltype = (label_type_t)ltype;
+	return EOK;
+}
+
+/** Create new label. */
+int vol_label_create(vol_t *vol, service_id_t sid, label_type_t ltype)
+{
+	async_exch_t *exch;
+	int retval;
+
+	exch = async_exchange_begin(vol->sess);
+	retval = async_req_2_0(exch, VOL_LABEL_CREATE, sid, ltype);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** Erase disk (to the extent where we will consider it not containing
+ * a label or file system. */
+int vol_disk_empty(vol_t *vol, service_id_t sid)
+{
+	async_exch_t *exch;
+	int retval;
+
+	exch = async_exchange_begin(vol->sess);
+	retval = async_req_1_0(exch, VOL_DISK_EMPTY, sid);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/vbd.h
===================================================================
--- uspace/lib/c/include/ipc/vbd.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/include/ipc/vbd.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+
+#ifndef LIBC_IPC_VBD_H_
+#define LIBC_IPC_VBD_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	VBD_DISK_ADD = IPC_FIRST_USER_METHOD,
+	VBD_DISK_REMOVE,
+	VBD_DISK_INFO,
+	VBD_LABEL_CREATE,
+	VBD_LABEL_DELETE
+} vbd_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/vol.h
===================================================================
--- uspace/lib/c/include/ipc/vol.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/include/ipc/vol.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+
+#ifndef LIBC_IPC_VOL_H_
+#define LIBC_IPC_VOL_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	VOL_GET_DISKS = IPC_FIRST_USER_METHOD,
+	VOL_DISK_INFO,
+	VOL_LABEL_CREATE,
+	VOL_DISK_EMPTY
+} vol_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/label.h
===================================================================
--- uspace/lib/c/include/types/label.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/include/types/label.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_TYPES_LABEL_H_
+#define LIBC_TYPES_LABEL_H_
+
+/** Disk contents */
+typedef enum {
+	/** Disk is considered empty */
+	dc_empty = 0,
+	/** Disk contains a recognized label */
+	dc_label,
+	/** Disk contains a recognized filesystem */
+	dc_fs,
+	/** Disk contains unrecognized data */
+	dc_unknown
+} label_disk_cnt_t;
+
+/** Disk label type */
+typedef enum {
+	/** BIOS Master Boot Record */
+	lt_mbr,
+	/** UEFI GUID Partition Table */
+	lt_gpt
+} label_type_t;
+
+#define LT_LIMIT (lt_gpt + 1)
+
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/include/vbd.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_VBD_H_
+#define LIBC_VBD_H_
+
+#include <async.h>
+#include <loc.h>
+#include <types/label.h>
+
+/** VBD service */
+typedef struct vbd {
+	/** VBD session */
+	async_sess_t *sess;
+} vbd_t;
+
+/** Disk information */
+typedef struct {
+	/** Label type */
+	label_type_t ltype;
+} vbd_disk_info_t;
+
+extern int vbd_create(vbd_t **);
+extern void vbd_destroy(vbd_t *);
+extern int vbd_disk_add(vbd_t *, service_id_t);
+extern int vbd_disk_remove(vbd_t *, service_id_t);
+extern int vbd_disk_info(vbd_t *, service_id_t, vbd_disk_info_t *);
+extern int vbd_label_create(vbd_t *, service_id_t, label_type_t);
+extern int vbd_label_delete(vbd_t *, service_id_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/lib/c/include/vol.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_VOL_H_
+#define LIBC_VOL_H_
+
+#include <async.h>
+#include <loc.h>
+#include <stdint.h>
+#include <types/label.h>
+
+/** Volume service */
+typedef struct vol {
+	/** Volume service session */
+	async_sess_t *sess;
+} vol_t;
+
+/** Disk information */
+typedef struct {
+	/** Disk contents */
+	label_disk_cnt_t dcnt;
+	/** Label type, if disk contents is label */
+	label_type_t ltype;
+} vol_disk_info_t;
+
+extern int vol_create(vol_t **);
+extern void vol_destroy(vol_t *);
+extern int vol_get_disks(vol_t *, service_id_t **, size_t *);
+extern int vol_disk_info(vol_t *, service_id_t, vol_disk_info_t *);
+extern int vol_label_create(vol_t *, service_id_t, label_type_t);
+extern int vol_disk_empty(vol_t *, service_id_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/lib/fdisk/include/fdisk.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -40,5 +40,7 @@
 #include <types/fdisk.h>
 
-extern int fdisk_dev_list_get(fdisk_dev_list_t **);
+extern int fdisk_create(fdisk_t **);
+extern void fdisk_destroy(fdisk_t *);
+extern int fdisk_dev_list_get(fdisk_t *, fdisk_dev_list_t **);
 extern void fdisk_dev_list_free(fdisk_dev_list_t *);
 extern fdisk_dev_info_t *fdisk_dev_first(fdisk_dev_list_t *);
@@ -48,5 +50,5 @@
 extern int fdisk_dev_info_capacity(fdisk_dev_info_t *, fdisk_cap_t *);
 
-extern int fdisk_dev_open(service_id_t, fdisk_dev_t **);
+extern int fdisk_dev_open(fdisk_t *, service_id_t, fdisk_dev_t **);
 extern void fdisk_dev_close(fdisk_dev_t *);
 extern int fdisk_dev_get_svcname(fdisk_dev_t *, char **);
@@ -54,5 +56,5 @@
 
 extern int fdisk_label_get_info(fdisk_dev_t *, fdisk_label_info_t *);
-extern int fdisk_label_create(fdisk_dev_t *, fdisk_label_type_t);
+extern int fdisk_label_create(fdisk_dev_t *, label_type_t);
 extern int fdisk_label_destroy(fdisk_dev_t *);
 
@@ -68,5 +70,5 @@
 extern int fdisk_cap_format(fdisk_cap_t *, char **);
 extern int fdisk_cap_parse(const char *, fdisk_cap_t *);
-extern int fdisk_ltype_format(fdisk_label_type_t, char **);
+extern int fdisk_ltype_format(label_type_t, char **);
 extern int fdisk_fstype_format(fdisk_fstype_t, char **);
 
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -40,4 +40,6 @@
 #include <loc.h>
 #include <stdint.h>
+#include <types/label.h>
+#include <vol.h>
 
 typedef enum {
@@ -95,36 +97,21 @@
 } fdisk_dev_info_t;
 
-/** Fdisk label type */
-typedef enum {
-	/** None */
-	fdl_none = 0,
-	/** Unknown */
-	fdl_unknown,
-	/** BIOS Master Boot Record */
-	fdl_mbr,
-	/** UEFI GUID Partition Table */
-	fdl_gpt
-} fdisk_label_type_t;
-
-/** Highest label type + 1 */
-#define FDL_LIMIT (fdl_gpt + 1)
-/** Lowest label type allowed for creation */
-#define FDL_CREATE_LO fdl_mbr
-/** Highest label type allowed for creation + 1 */
-#define FDL_CREATE_HI (fdl_gpt + 1)
-
 /** Open fdisk device */
 typedef struct {
-	/** Label type */
-	fdisk_label_type_t ltype;
+	/** Fdisk instance */
+	struct fdisk *fdisk;
+	/** Disk contents */
+	label_disk_cnt_t dcnt;
+	/** Service ID */
+	service_id_t sid;
 	/** Partitions */
 	list_t parts; /* of fdisk_part_t */
-	/** Service ID */
-	service_id_t sid;
 } fdisk_dev_t;
 
 typedef struct {
+	/** Disk contents */
+	label_disk_cnt_t dcnt;
 	/** Label type */
-	fdisk_label_type_t ltype;
+	label_type_t ltype;
 } fdisk_label_info_t;
 
@@ -156,4 +143,10 @@
 } fdisk_part_info_t;
 
+/** Fdisk instance */
+typedef struct fdisk {
+	/** Volume service */
+	vol_t *vol;
+} fdisk_t;
+
 #endif
 
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/lib/fdisk/src/fdisk.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -43,4 +43,5 @@
 #include <stdlib.h>
 #include <str.h>
+#include <vol.h>
 
 static const char *cu_str[] = {
@@ -68,9 +69,33 @@
 }
 
-int fdisk_dev_list_get(fdisk_dev_list_t **rdevlist)
+int fdisk_create(fdisk_t **rfdisk)
+{
+	fdisk_t *fdisk;
+	int rc;
+
+	fdisk = calloc(1, sizeof(fdisk_t));
+	if (fdisk == NULL)
+		return ENOMEM;
+
+	rc = vol_create(&fdisk->vol);
+	if (rc != EOK) {
+		free(fdisk);
+		return EIO;
+	}
+
+	*rfdisk = fdisk;
+	return EOK;
+}
+
+void fdisk_destroy(fdisk_t *fdisk)
+{
+	vol_destroy(fdisk->vol);
+	free(fdisk);
+}
+
+int fdisk_dev_list_get(fdisk_t *fdisk, fdisk_dev_list_t **rdevlist)
 {
 	fdisk_dev_list_t *devlist = NULL;
 	fdisk_dev_info_t *info;
-	category_id_t disk_cat;
 	service_id_t *svcs = NULL;
 	size_t count, i;
@@ -83,11 +108,5 @@
 	list_initialize(&devlist->devinfos);
 
-	rc = loc_category_get_id("disk", &disk_cat, 0);
-	if (rc != EOK) {
-		rc = EIO;
-		goto error;
-	}
-
-	rc = loc_category_get_svcs(disk_cat, &svcs, &count);
+	rc = vol_get_disks(fdisk->vol, &svcs, &count);
 	if (rc != EOK) {
 		rc = EIO;
@@ -210,5 +229,5 @@
 }
 
-int fdisk_dev_open(service_id_t sid, fdisk_dev_t **rdev)
+int fdisk_dev_open(fdisk_t *fdisk, service_id_t sid, fdisk_dev_t **rdev)
 {
 	fdisk_dev_t *dev;
@@ -218,5 +237,5 @@
 		return ENOMEM;
 
-	dev->ltype = fdl_none;
+	dev->fdisk = fdisk;
 	dev->sid = sid;
 	list_initialize(&dev->parts);
@@ -271,15 +290,23 @@
 int fdisk_label_get_info(fdisk_dev_t *dev, fdisk_label_info_t *info)
 {
-	info->ltype = dev->ltype;
-	return EOK;
-}
-
-int fdisk_label_create(fdisk_dev_t *dev, fdisk_label_type_t ltype)
-{
-	if (dev->ltype != fdl_none)
-		return EEXISTS;
-
-	dev->ltype = ltype;
-	return EOK;
+	vol_disk_info_t vinfo;
+	int rc;
+
+	rc = vol_disk_info(dev->fdisk->vol, dev->sid, &vinfo);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	info->dcnt = vinfo.dcnt;
+	info->ltype = vinfo.ltype;
+	return EOK;
+error:
+	return rc;
+}
+
+int fdisk_label_create(fdisk_dev_t *dev, label_type_t ltype)
+{
+	return vol_label_create(dev->fdisk->vol, dev->sid, ltype);
 }
 
@@ -287,7 +314,5 @@
 {
 	fdisk_part_t *part;
-
-	if (dev->ltype == fdl_none)
-		return ENOENT;
+	int rc;
 
 	part = fdisk_part_first(dev);
@@ -297,5 +322,9 @@
 	}
 
-	dev->ltype = fdl_none;
+	rc = vol_disk_empty(dev->fdisk->vol, dev->sid);
+	if (rc != EOK)
+		return EIO;
+
+	dev->dcnt = dc_empty;
 	return EOK;
 }
@@ -419,5 +448,5 @@
 }
 
-int fdisk_ltype_format(fdisk_label_type_t ltype, char **rstr)
+int fdisk_ltype_format(label_type_t ltype, char **rstr)
 {
 	const char *sltype;
@@ -426,14 +455,8 @@
 	sltype = NULL;
 	switch (ltype) {
-	case fdl_none:
-		sltype = "None";
-		break;
-	case fdl_unknown:
-		sltype = "Unknown";
-		break;
-	case fdl_mbr:
+	case lt_mbr:
 		sltype = "MBR";
 		break;
-	case fdl_gpt:
+	case lt_gpt:
 		sltype = "GPT";
 		break;
Index: uspace/srv/bd/vbd/types/vbd.h
===================================================================
--- uspace/srv/bd/vbd/types/vbd.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
+++ uspace/srv/bd/vbd/types/vbd.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup vbd
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef TYPES_VBD_H_
+#define TYPES_VBD_H_
+
+#include <types/label.h>
+
+/** Disk info */
+typedef struct {
+	/** Label type */
+	label_type_t ltype;
+} vbd_disk_info_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/bd/vbd/vbd.c
===================================================================
--- uspace/srv/bd/vbd/vbd.c	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/srv/bd/vbd/vbd.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup dnsres
+/** @addtogroup vbd
  * @{
  */
@@ -38,4 +38,5 @@
 #include <io/log.h>
 #include <ipc/services.h>
+#include <ipc/vbd.h>
 #include <loc.h>
 #include <stdio.h>
@@ -43,4 +44,6 @@
 #include <task.h>
 
+#include "types/vbd.h"
+
 #define NAME  "vbd"
 
@@ -50,5 +53,5 @@
 {
 	int rc;
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_init()");
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_init()");
 
 	async_set_client_connection(vbd_client_conn);
@@ -70,8 +73,105 @@
 }
 
+static int vbd_disk_add(service_id_t sid)
+{
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_add(%zu)", sid);
+	return EOK;
+}
+
+static int vbd_disk_remove(service_id_t sid)
+{
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_remove(%zu)", sid);
+	return EOK;
+}
+
+static int vbd_disk_info(service_id_t sid, vbd_disk_info_t *info)
+{
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info(%zu)", sid);
+	info->ltype = lt_mbr;
+	return EOK;
+}
+
+static int vbd_label_create(service_id_t sid, label_type_t ltype)
+{
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_label_create(%zu, %d)", sid,
+	    ltype);
+	return EOK;
+}
+
+static int vbd_label_delete(service_id_t sid, label_type_t ltype)
+{
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_label_delete(%zu, %d)", sid,
+	    ltype);
+	return EOK;
+}
+
+static void vbd_disk_add_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t disk_sid;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_add_srv()");
+
+	disk_sid = IPC_GET_ARG1(*icall);
+	rc = vbd_disk_add(disk_sid);
+	async_answer_0(iid, (sysarg_t) rc);
+}
+
+static void vbd_disk_remove_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t disk_sid;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_remove_srv()");
+
+	disk_sid = IPC_GET_ARG1(*icall);
+	rc = vbd_disk_remove(disk_sid);
+	async_answer_0(iid, (sysarg_t) rc);
+}
+
+static void vbd_disk_info_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t disk_sid;
+	vbd_disk_info_t dinfo;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info_srv()");
+
+	disk_sid = IPC_GET_ARG1(*icall);
+	rc = vbd_disk_info(disk_sid, &dinfo);
+	async_answer_1(iid, (sysarg_t)rc, (sysarg_t)dinfo.ltype);
+}
+
+static void vbd_label_create_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t disk_sid;
+	label_type_t ltype;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_label_create_srv()");
+
+	disk_sid = IPC_GET_ARG1(*icall);
+	ltype = IPC_GET_ARG2(*icall);
+	rc = vbd_label_create(disk_sid, ltype);
+	async_answer_0(iid, (sysarg_t) rc);
+}
+
+static void vbd_label_delete_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t disk_sid;
+	label_type_t ltype;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_label_delete_srv()");
+
+	disk_sid = IPC_GET_ARG1(*icall);
+	ltype = IPC_GET_ARG2(*icall);
+	rc = vbd_label_delete(disk_sid, ltype);
+	async_answer_0(iid, (sysarg_t) rc);
+}
 
 static void vbd_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_client_conn()");
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_client_conn()");
 
 	/* Accept the connection */
@@ -90,4 +190,19 @@
 
 		switch (method) {
+		case VBD_DISK_ADD:
+			vbd_disk_add_srv(callid, &call);
+			break;
+		case VBD_DISK_REMOVE:
+			vbd_disk_remove_srv(callid, &call);
+			break;
+		case VBD_DISK_INFO:
+			vbd_disk_info_srv(callid, &call);
+			break;
+		case VBD_LABEL_CREATE:
+			vbd_label_create_srv(callid, &call);
+			break;
+		case VBD_LABEL_DELETE:
+			vbd_label_delete_srv(callid, &call);
+			break;
 		default:
 			async_answer_0(callid, EINVAL);
Index: uspace/srv/volsrv/disk.c
===================================================================
--- uspace/srv/volsrv/disk.c	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/srv/volsrv/disk.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -42,4 +42,5 @@
 #include <stdlib.h>
 #include <str.h>
+#include <vbd.h>
 
 #include "disk.h"
@@ -48,6 +49,7 @@
 static int vol_disk_add(service_id_t);
 
-static LIST_INITIALIZE(vol_disks);
+static LIST_INITIALIZE(vol_disks); /* of vol_disk_t */
 static FIBRIL_MUTEX_INITIALIZE(vol_disks_lock);
+static vbd_t *vbd;
 
 /** Check for new disk devices */
@@ -113,4 +115,5 @@
 
 	link_initialize(&disk->ldisks);
+	disk->dcnt = dc_empty;
 
 	return disk;
@@ -129,4 +132,5 @@
 {
 	vol_disk_t *disk;
+	vbd_disk_info_t dinfo;
 	int rc;
 
@@ -147,11 +151,26 @@
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe disk %s", disk->svc_name);
-/*	rc = inetcfg_link_add(sid);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed configuring link "
-		    "'%s'.\n", nlink->svc_name);
-		goto error;
-	}
-*/
+
+	rc = vbd_disk_add(vbd, sid);
+	if (rc == EOK) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Disk %s accepted by VBD.",
+		    disk->svc_name);
+
+		rc = vbd_disk_info(vbd, sid, &dinfo);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_NOTE, "Cannot get disk label "
+			    "information.");
+			rc = EIO;
+			goto error;
+		}
+
+		disk->dcnt = dc_label;
+		disk->ltype = dinfo.ltype;
+	} else {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Disk %s not accepted by VBD.",
+		    disk->svc_name);
+		disk->dcnt = dc_unknown;
+	}
+
 	list_append(&disk->ldisks, &vol_disks);
 
@@ -168,4 +187,17 @@
 }
 
+int vol_disk_init(void)
+{
+	int rc;
+
+	rc = vbd_create(&vbd);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing VBD.");
+		return EIO;
+	}
+
+	return EOK;
+}
+
 int vol_disk_discovery_start(void)
 {
@@ -182,4 +214,46 @@
 }
 
+/** Get list of disks as array of service IDs. */
+int vol_disk_get_ids(service_id_t *id_buf, size_t buf_size, size_t *act_size)
+{
+	size_t act_cnt;
+	size_t buf_cnt;
+
+	fibril_mutex_lock(&vol_disks_lock);
+
+	buf_cnt = buf_size / sizeof(service_id_t);
+
+	act_cnt = list_count(&vol_disks);
+	*act_size = act_cnt * sizeof(service_id_t);
+
+	if (buf_size % sizeof(service_id_t) != 0) {
+		fibril_mutex_unlock(&vol_disks_lock);
+		return EINVAL;
+	}
+
+	size_t pos = 0;
+	list_foreach(vol_disks, ldisks, vol_disk_t, disk) {
+		if (pos < buf_cnt)
+			id_buf[pos] = disk->svc_id;
+		pos++;
+	}
+
+	fibril_mutex_unlock(&vol_disks_lock);
+	return EOK;
+}
+
+int vol_disk_find_by_id(service_id_t sid, vol_disk_t **rdisk)
+{
+	list_foreach(vol_disks, ldisks, vol_disk_t, disk) {
+		if (disk->svc_id == sid) {
+			*rdisk = disk;
+			/* XXX Add reference */
+			return EOK;
+		}
+	}
+
+	return ENOENT;
+}
+
 /** @}
  */
Index: uspace/srv/volsrv/disk.h
===================================================================
--- uspace/srv/volsrv/disk.h	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/srv/volsrv/disk.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -39,6 +39,10 @@
 
 #include <sys/types.h>
+#include "types/disk.h"
 
+extern int vol_disk_init(void);
 extern int vol_disk_discovery_start(void);
+extern int vol_disk_get_ids(service_id_t *, size_t, size_t *);
+extern int vol_disk_find_by_id(service_id_t, vol_disk_t **);
 
 #endif
Index: uspace/srv/volsrv/types/disk.h
===================================================================
--- uspace/srv/volsrv/types/disk.h	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/srv/volsrv/types/disk.h	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -38,4 +38,6 @@
 #define TYPES_DISK_H_
 
+#include <types/label.h>
+
 /** Disk */
 typedef struct {
@@ -46,4 +48,8 @@
 	/** Service name */
 	char *svc_name;
+	/** Disk contents */
+	label_disk_cnt_t dcnt;
+	/** Label type */
+	label_type_t ltype;
 } vol_disk_t;
 
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision 1356f85ab4d59ae2070c30ebad2252295c6532ac)
+++ uspace/srv/volsrv/volsrv.c	(revision 22fb7ab62c90645d53594ec9d4efb3974dd3167f)
@@ -38,4 +38,5 @@
 #include <io/log.h>
 #include <ipc/services.h>
+#include <ipc/vol.h>
 #include <loc.h>
 #include <stdio.h>
@@ -54,4 +55,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_init()");
 
+	rc = vol_disk_init();
+	if (rc != EOK)
+		return rc;
+
 	rc = vol_disk_discovery_start();
 	if (rc != EOK)
@@ -76,4 +81,93 @@
 }
 
+static void vol_get_disks_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	size_t size;
+	size_t act_size;
+	int rc;
+
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	service_id_t *id_buf = (service_id_t *) malloc(size);
+	if (id_buf == NULL) {
+		async_answer_0(callid, ENOMEM);
+		async_answer_0(iid, ENOMEM);
+		return;
+	}
+
+	rc = vol_disk_get_ids(id_buf, size, &act_size);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
+	free(id_buf);
+
+	async_answer_1(iid, retval, act_size);
+}
+
+static void vol_disk_info_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t sid;
+	vol_disk_t *disk;
+	int rc;
+
+	sid = IPC_GET_ARG1(*icall);
+	rc = vol_disk_find_by_id(sid, &disk);
+	if (rc != EOK) {
+		async_answer_0(iid, ENOENT);
+		return;
+	}
+
+	async_answer_2(iid, rc, disk->dcnt, disk->ltype);
+}
+
+static void vol_label_create_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t sid;
+	vol_disk_t *disk;
+	label_type_t ltype;
+	int rc;
+
+	sid = IPC_GET_ARG1(*icall);
+	ltype = IPC_GET_ARG2(*icall);
+
+	rc = vol_disk_find_by_id(sid, &disk);
+	if (rc != EOK) {
+		async_answer_0(iid, ENOENT);
+		return;
+	}
+
+	disk->dcnt = dc_label;
+	disk->ltype = ltype;
+
+	async_answer_0(iid, EOK);
+}
+
+static void vol_disk_empty_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t sid;
+	vol_disk_t *disk;
+	int rc;
+
+	sid = IPC_GET_ARG1(*icall);
+
+	rc = vol_disk_find_by_id(sid, &disk);
+	if (rc != EOK) {
+		async_answer_0(iid, ENOENT);
+		return;
+	}
+
+	disk->dcnt = dc_empty;
+
+	async_answer_0(iid, EOK);
+}
 
 static void vol_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -96,4 +190,16 @@
 
 		switch (method) {
+		case VOL_GET_DISKS:
+			vol_get_disks_srv(callid, &call);
+			break;
+		case VOL_DISK_INFO:
+			vol_disk_info_srv(callid, &call);
+			break;
+		case VOL_LABEL_CREATE:
+			vol_label_create_srv(callid, &call);
+			break;
+		case VOL_DISK_EMPTY:
+			vol_disk_empty_srv(callid, &call);
+			break;
 		default:
 			async_answer_0(callid, EINVAL);
