Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 2654afbde2adc86cb19dddeb6edeb7ad9308db21)
+++ uspace/Makefile	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -45,4 +45,5 @@
 	app/download \
 	app/edit \
+	app/fdisk \
 	app/fontviewer \
 	app/getterm \
@@ -217,4 +218,5 @@
 	lib/crypto \
 	lib/clui \
+	lib/fdisk \
 	lib/fmtutil \
 	lib/scsi \
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 2654afbde2adc86cb19dddeb6edeb7ad9308db21)
+++ uspace/Makefile.common	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -122,4 +122,5 @@
 LIBCRYPTO_PREFIX = $(LIB_PREFIX)/crypto
 LIBBLOCK_PREFIX = $(LIB_PREFIX)/block
+LIBFDISK_PREFIX = $(LIB_PREFIX)/fdisk
 LIBFS_PREFIX = $(LIB_PREFIX)/fs
 LIBCLUI_PREFIX = $(LIB_PREFIX)/clui
Index: uspace/app/fdisk/Makefile
===================================================================
--- uspace/app/fdisk/Makefile	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/app/fdisk/Makefile	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = \
+	$(LIBCLUI_PREFIX)/libclui.a \
+	$(LIBFDISK_PREFIX)/libfdisk.a \
+	$(LIBBLOCK_PREFIX)/libblock.a
+
+EXTRA_CFLAGS = \
+	-I$(LIBCLUI_PREFIX) \
+	-I$(LIBFDISK_PREFIX)/include
+
+BINARY = fdisk
+
+SOURCES = \
+	fdisk.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/app/fdisk/fdisk.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,372 @@
+/*
+ * 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 fdisk
+ * @brief Disk management tool
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <errno.h>
+#include <nchoice.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fdisk.h>
+
+static bool quit = false;
+
+/** Device menu actions */
+typedef enum {
+	/** Create label */
+	devac_create_label,
+	/** Delete label */
+	devac_delete_label,
+	/** Create partition */
+	devac_create_part,
+	/** Delete partition */
+	devac_delete_part,
+	/** Exit */
+	devac_exit
+} devac_t;
+
+/** Device selection */
+static int fdsk_dev_sel_choice(service_id_t *rsvcid)
+{
+	fdisk_dev_list_t *devlist = NULL;
+	fdisk_dev_info_t *info;
+	nchoice_t *choice = NULL;
+	char *svcname = NULL;
+	fdisk_cap_t cap;
+	char *scap = NULL;
+	char *dtext = NULL;
+	service_id_t svcid;
+	void *sel;
+	int rc;
+
+	rc = nchoice_create(&choice);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_set_prompt(choice, "Select device");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = fdisk_dev_list_get(&devlist);
+	if (rc != EOK) {
+		printf("Error getting device list.\n");
+		goto error;
+	}
+
+	info = fdisk_dev_first(devlist);
+	while (info != NULL) {
+		rc = fdisk_dev_get_svcname(info, &svcname);
+		if (rc != EOK) {
+			printf("Error getting device service name.\n");
+			goto error;
+		}
+
+		rc = fdisk_dev_capacity(info, &cap);
+		if (rc != EOK) {
+			printf("Error getting device capacity.\n");
+			goto error;
+		}
+
+		rc = fdisk_cap_format(&cap, &scap);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		rc = asprintf(&dtext, "%s (%s)", svcname, scap);
+		if (rc < 0) {
+			rc = ENOMEM;
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		free(svcname);
+		svcname = NULL;
+		free(scap);
+		scap = NULL;
+
+		rc = nchoice_add(choice, dtext, info);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+
+		free(dtext);
+		dtext = NULL;
+
+		info = fdisk_dev_next(info);
+	}
+
+	rc = nchoice_get(choice, &sel);
+	if (rc != EOK) {
+		printf("Error getting user selection.\n");
+		return rc;
+	}
+
+	fdisk_dev_get_svcid((fdisk_dev_info_t *)sel, &svcid);
+	fdisk_dev_list_free(devlist);
+
+	printf("Selected dev with sid=%zu\n", svcid);
+
+	nchoice_destroy(choice);
+	*rsvcid = svcid;
+	return EOK;
+error:
+	if (devlist != NULL)
+		fdisk_dev_list_free(devlist);
+	if (choice != NULL)
+		nchoice_destroy(choice);
+	free(dtext);
+	free(svcname);
+	free(scap);
+	return rc;
+}
+
+static int fdsk_create_label(fdisk_dev_t *dev)
+{
+	nchoice_t *choice = NULL;
+	void *sel;
+	int rc;
+
+	rc = nchoice_create(&choice);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_set_prompt(choice, "Select label type");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_add(choice, "GPT", (void *)fdl_gpt);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_add(choice, "MBR", (void *)fdl_mbr);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_get(choice, &sel);
+	if (rc != EOK) {
+		printf("Error getting user selection.\n");
+		goto error;
+	}
+
+	rc = fdisk_label_create(dev, (fdisk_label_type_t)sel);
+	if (rc != EOK) {
+		printf("Error creating label.\n");
+		goto error;
+	}
+
+	nchoice_destroy(choice);
+	return EOK;
+error:
+	if (choice != NULL)
+		nchoice_destroy(choice);
+	return rc;
+}
+
+/** Device menu */
+static int fdsk_dev_menu(fdisk_dev_t *dev)
+{
+	nchoice_t *choice = NULL;
+	fdisk_label_info_t linfo;
+	char *sltype = NULL;
+	int rc;
+	void *sel;
+
+	rc = nchoice_create(&choice);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_set_prompt(choice, "Select action");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	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("Label type: %s\n", sltype);
+	free(sltype);
+	sltype = NULL;
+
+	rc = nchoice_set_prompt(choice, "Select action");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	if (linfo.ltype == fdl_none) {
+		rc = nchoice_add(choice, "Create label",
+		    (void *)devac_create_label);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+	} else {
+		rc = nchoice_add(choice, "Delete label",
+		    (void *)devac_delete_label);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+	}
+
+	rc = nchoice_add(choice, "Create partition",
+	    (void *)devac_create_part);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_add(choice, "Delete partition",
+	    (void *)devac_delete_part);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_add(choice, "Exit", (void *)devac_exit);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		printf("Out of memory.\n");
+		goto error;
+	}
+
+	rc = nchoice_get(choice, &sel);
+	if (rc != EOK) {
+		printf("Error getting user selection.\n");
+		return rc;
+	}
+
+	switch ((devac_t)sel) {
+	case devac_create_label:
+		rc = fdsk_create_label(dev);
+		if (rc != EOK)
+			goto error;
+		break;
+	case devac_delete_label:
+		rc = fdisk_label_destroy(dev);
+		if (rc != EOK)
+			goto error;
+		break;
+	case devac_create_part:
+		break;
+	case devac_delete_part:
+		break;
+	case devac_exit:
+		quit = true;
+		break;
+	}
+
+	nchoice_destroy(choice);
+	return EOK;
+error:
+	if (choice != NULL)
+		nchoice_destroy(choice);
+	return rc;
+}
+
+int main(int argc, char *argv[])
+{
+	service_id_t svcid;
+	fdisk_dev_t *dev;
+	int rc;
+
+	rc = fdsk_dev_sel_choice(&svcid);
+	if (rc != EOK)
+		return 1;
+
+	rc = fdisk_dev_open(svcid, &dev);
+	if (rc != EOK) {
+		printf("Error opening device.\n");
+		return 1;
+	}
+
+	while (!quit) {
+		rc = fdsk_dev_menu(dev);
+		if (rc != EOK) {
+			fdisk_dev_close(dev);
+			return 1;
+		}
+	}
+
+	fdisk_dev_close(dev);
+
+	return 0;
+}
+
+
+/** @}
+ */
Index: uspace/drv/block/ata_bd/main.c
===================================================================
--- uspace/drv/block/ata_bd/main.c	(revision 2654afbde2adc86cb19dddeb6edeb7ad9308db21)
+++ uspace/drv/block/ata_bd/main.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -200,4 +200,5 @@
 
 	ddf_fun_add_to_category(fun, "bd");
+	ddf_fun_add_to_category(fun, "disk");
 
 	free(fun_name);
Index: uspace/lib/clui/Makefile
===================================================================
--- uspace/lib/clui/Makefile	(revision 2654afbde2adc86cb19dddeb6edeb7ad9308db21)
+++ uspace/lib/clui/Makefile	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -32,4 +32,5 @@
 
 SOURCES = \
+	nchoice.c \
 	tinput.c
 
Index: uspace/lib/clui/nchoice.c
===================================================================
--- uspace/lib/clui/nchoice.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/lib/clui/nchoice.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,172 @@
+/*
+ * 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 libclui
+ * @{
+ */
+/**
+ * @file Numerical choice
+ */
+
+#include <errno.h>
+#include <nchoice.h>
+#include <stdlib.h>
+#include <str.h>
+#include <tinput.h>
+
+/** Create numerical choice
+ *
+ */
+int nchoice_create(nchoice_t **rchoice)
+{
+	nchoice_t *choice = NULL;
+	int rc;
+
+	choice = calloc(1, sizeof(nchoice_t));
+	if (choice == NULL)
+		goto error;
+
+	list_initialize(&choice->opts);
+
+	choice->tinput = tinput_new();
+	if (choice->tinput == NULL)
+		goto error;
+
+	rc = tinput_set_prompt(choice->tinput, "Choice> ");
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		goto error;
+	}
+
+	*rchoice = choice;
+	return EOK;
+error:
+	nchoice_destroy(choice);
+	return ENOMEM;
+}
+
+/** Destroy numerical choice */
+void nchoice_destroy(nchoice_t *choice)
+{
+	if (choice == NULL)
+		return;
+
+	tinput_destroy(choice->tinput);
+	free(choice);
+}
+
+/** Set numerica choice prompt text */
+int nchoice_set_prompt(nchoice_t *choice, const char *prompt)
+{
+	char *pstr;
+
+	pstr = str_dup(prompt);
+	if (pstr == NULL)
+		return ENOMEM;
+
+	free(choice->prompt);
+	choice->prompt = pstr;
+	return EOK;
+}
+
+#include <stdio.h>
+/** Add option to numerical choice */
+int nchoice_add(nchoice_t *choice, const char *opttext, void *arg)
+{
+	nchoice_opt_t *opt;
+	char *ptext;
+
+	opt = calloc(1, sizeof(nchoice_opt_t));
+	if (opt == NULL)
+		return ENOMEM;
+
+	ptext = str_dup(opttext);
+	if (ptext == NULL) {
+		free(opt);
+		return ENOMEM;
+	}
+
+	opt->text = ptext;
+	opt->arg = arg;
+	list_append(&opt->lchoice, &choice->opts);
+	return EOK;
+}
+
+/** Get numerical choice from user */
+int nchoice_get(nchoice_t *choice, void **rarg)
+{
+	int i;
+	int rc;
+	char *str;
+	unsigned long c;
+	char *eptr;
+
+again:
+	printf("%s\n", choice->prompt);
+
+	i = 1;
+	list_foreach(choice->opts, lchoice, nchoice_opt_t, opt) {
+		printf("%d: %s\n", i, opt->text);
+		++i;
+	}
+
+	rc = tinput_read(choice->tinput, &str);
+	if (rc != EOK) {
+		assert(rc == EIO || rc == ENOENT);
+
+		if (rc == ENOENT) {
+			return ENOENT;
+		} else {
+			/* rc == EIO */
+			return EIO;
+		}
+	}
+
+	c = strtoul(str, &eptr, 10);
+	if (*eptr != '\0' || c < 1 || c > (unsigned long)i - 1) {
+		printf("Invalid choice. Try again.\n");
+		free(str);
+		goto again;
+	}
+
+	free(str);
+
+	i = 1;
+	list_foreach(choice->opts, lchoice, nchoice_opt_t, opt) {
+		if ((unsigned long)i == c) {
+			*rarg = opt->arg;
+			return EOK;
+		}
+		++i;
+	}
+
+	assert(false);
+	return ENOENT;
+}
+
+/** @}
+ */
Index: uspace/lib/clui/nchoice.h
===================================================================
--- uspace/lib/clui/nchoice.h	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/lib/clui/nchoice.h	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,69 @@
+/*
+ * 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 libclui
+ * @{
+ */
+/**
+ * @file Numerical choice
+ */
+
+#ifndef LIBCLUI_NCHOICE_H_
+#define LIBCLUI_NCHOICE_H_
+
+#include <adt/list.h>
+#include <tinput.h>
+
+typedef struct {
+	/** Link to nchoice_t.opts */
+	link_t lchoice;
+	/** Option text */
+	char *text;
+	/** User argument */
+	void *arg;
+} nchoice_opt_t;
+
+typedef struct {
+	/** Prompt text */
+	char *prompt;
+	/** Options */
+	list_t opts; /* of nchoice_opt_t */
+	/** Text input */
+	tinput_t *tinput;
+} nchoice_t;
+
+extern int nchoice_create(nchoice_t **);
+extern void nchoice_destroy(nchoice_t *);
+extern int nchoice_set_prompt(nchoice_t *, const char *);
+extern int nchoice_add(nchoice_t *, const char *, void *);
+extern int nchoice_get(nchoice_t *, void **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/fdisk/Makefile
===================================================================
--- uspace/lib/fdisk/Makefile	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/lib/fdisk/Makefile	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -Iinclude -I$(LIBBLOCK_PREFIX)
+
+LIBRARY = libfdisk
+
+SOURCES = \
+	src/fdisk.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/lib/fdisk/include/fdisk.h	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,70 @@
+/*
+ * 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 libfdisk
+ * @{
+ */
+/**
+ * @file Disk management library.
+ */
+
+#ifndef LIBFDISK_FDISK_H_
+#define LIBFDISK_FDISK_H_
+
+#include <loc.h>
+#include <types/fdisk.h>
+
+extern int fdisk_dev_list_get(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 *);
+extern fdisk_dev_info_t *fdisk_dev_next(fdisk_dev_info_t *);
+extern int fdisk_dev_get_svcname(fdisk_dev_info_t *, char **);
+extern void fdisk_dev_get_svcid(fdisk_dev_info_t *, service_id_t *);
+extern int fdisk_dev_capacity(fdisk_dev_info_t *, fdisk_cap_t *);
+
+extern int fdisk_dev_open(service_id_t, fdisk_dev_t **);
+extern void fdisk_dev_close(fdisk_dev_t *);
+
+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_destroy(fdisk_dev_t *);
+
+extern fdisk_part_t *fdisk_part_first(fdisk_dev_t *);
+extern fdisk_part_t *fdisk_part_next(fdisk_part_t *);
+extern int fdisk_part_get_max_avail(fdisk_dev_t *, fdisk_cap_t *);
+extern int fdisk_part_create(fdisk_dev_t *, fdisk_partspec_t *,
+    fdisk_part_t **);
+extern int fdisk_part_destroy(fdisk_part_t *);
+
+extern int fdisk_cap_format(fdisk_cap_t *, char **);
+extern int fdisk_ltype_format(fdisk_label_type_t, char **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,111 @@
+/*
+ * 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 libfdisk
+ * @{
+ */
+/**
+ * @file Disk management library types.
+ */
+
+#ifndef LIBFDISK_TYPES_H_
+#define LIBFDISK_TYPES_H_
+
+#include <adt/list.h>
+#include <loc.h>
+#include <stdint.h>
+
+/** List of devices available for managing by fdisk */
+typedef struct {
+	list_t devinfos; /* of fdisk_dev_info_t */
+} fdisk_dev_list_t;
+
+/** Device information */
+typedef struct {
+	/** Containing device list */
+	fdisk_dev_list_t *devlist;
+	/** Link in fdisk_dev_list_t.devinfos */
+	link_t ldevlist;
+	service_id_t svcid;
+	/** Service name or NULL if not determined yet */
+	char *svcname;
+	bool blk_inited;
+} 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;
+
+/** Open fdisk device */
+typedef struct {
+	fdisk_label_type_t ltype;
+} fdisk_dev_t;
+
+typedef struct {
+	/** Label type */
+	fdisk_label_type_t ltype;
+} fdisk_label_info_t;
+
+/** Partition */
+typedef struct {
+} fdisk_part_t;
+
+typedef enum {
+	cu_byte = 0,
+	cu_kbyte,
+	cu_mbyte,
+	cu_gbyte,
+	cu_tbyte,
+	cu_pbyte,
+	cu_ebyte,
+	cu_zbyte,
+	cu_ybyte
+} fdisk_cunit_t;
+
+/** Partition capacity */
+typedef struct {
+	uint64_t value;
+	fdisk_cunit_t cunit;
+} fdisk_cap_t;
+
+/** Specification of new partition */
+typedef struct {
+} fdisk_partspec_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
+++ uspace/lib/fdisk/src/fdisk.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -0,0 +1,306 @@
+/*
+ * 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 libfdisk
+ * @{
+ */
+/**
+ * @file Disk management library.
+ */
+
+#include <adt/list.h>
+#include <block.h>
+#include <errno.h>
+#include <fdisk.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+
+static void fdisk_dev_info_delete(fdisk_dev_info_t *info)
+{
+	if (info == NULL)
+		return;
+
+	if (info->blk_inited)
+		block_fini(info->svcid);
+
+	free(info->svcname);
+	free(info);
+}
+
+int fdisk_dev_list_get(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;
+	int rc;
+
+	devlist = calloc(1, sizeof(fdisk_dev_list_t));
+	if (devlist == NULL)
+		return ENOMEM;
+
+	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);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	for (i = 0; i < count; i++) {
+		info = calloc(1, sizeof(fdisk_dev_info_t));
+		if (info == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		info->svcid = svcs[i];
+		info->devlist = devlist;
+		list_append(&info->ldevlist, &devlist->devinfos);
+	}
+
+	*rdevlist = devlist;
+	free(svcs);
+	return EOK;
+error:
+	free(svcs);
+	fdisk_dev_list_free(devlist);
+	return rc;
+}
+
+void fdisk_dev_list_free(fdisk_dev_list_t *devlist)
+{
+	fdisk_dev_info_t *info;
+
+	if (devlist == NULL)
+		return;
+
+	while (!list_empty(&devlist->devinfos)) {
+		info = list_get_instance(list_first(
+		    &devlist->devinfos), fdisk_dev_info_t,
+		    ldevlist);
+
+		list_remove(&info->ldevlist);
+		fdisk_dev_info_delete(info);
+	}
+
+	free(devlist);
+}
+
+fdisk_dev_info_t *fdisk_dev_first(fdisk_dev_list_t *devlist)
+{
+	if (list_empty(&devlist->devinfos))
+		return NULL;
+
+	return list_get_instance(list_first(&devlist->devinfos),
+	    fdisk_dev_info_t, ldevlist);
+}
+
+fdisk_dev_info_t *fdisk_dev_next(fdisk_dev_info_t *devinfo)
+{
+	link_t *lnext;
+
+	lnext = list_next(&devinfo->ldevlist,
+	    &devinfo->devlist->devinfos);
+	if (lnext == NULL)
+		return NULL;
+
+	return list_get_instance(lnext, fdisk_dev_info_t,
+	    ldevlist);
+}
+
+void fdisk_dev_get_svcid(fdisk_dev_info_t *info, service_id_t *rsid)
+{
+	*rsid = info->svcid;
+}
+
+int fdisk_dev_get_svcname(fdisk_dev_info_t *info, char **rname)
+{
+	char *name;
+	int rc;
+
+	if (info->svcname == NULL) {
+		rc = loc_service_get_name(info->svcid,
+		    &info->svcname);
+		if (rc != EOK)
+			return rc;
+	}
+
+	name = str_dup(info->svcname);
+	if (name == NULL)
+		return ENOMEM;
+
+	*rname = name;
+	return EOK;
+}
+
+int fdisk_dev_capacity(fdisk_dev_info_t *info, fdisk_cap_t *cap)
+{
+	size_t bsize;
+	aoff64_t nblocks;
+	int rc;
+
+	if (!info->blk_inited) {
+		rc = block_init(EXCHANGE_SERIALIZE, info->svcid, 2048);
+		if (rc != EOK)
+			return rc;
+	}
+
+	rc = block_get_bsize(info->svcid, &bsize);
+	if (rc != EOK)
+		return EIO;
+
+	rc = block_get_nblocks(info->svcid, &nblocks);
+	if (rc != EOK)
+		return EIO;
+
+	cap->value = bsize * nblocks;
+	cap->cunit = cu_byte;
+
+	return EOK;
+}
+
+int fdisk_dev_open(service_id_t sid, fdisk_dev_t **rdev)
+{
+	fdisk_dev_t *dev;
+
+	dev = calloc(1, sizeof(fdisk_dev_t));
+	if (dev == NULL)
+		return ENOMEM;
+
+	dev->ltype = fdl_none;
+	*rdev = dev;
+	return EOK;
+}
+
+void fdisk_dev_close(fdisk_dev_t *dev)
+{
+	free(dev);
+}
+
+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;
+}
+
+int fdisk_label_destroy(fdisk_dev_t *dev)
+{
+	if (dev->ltype == fdl_none)
+		return ENOENT;
+
+	dev->ltype = fdl_none;
+	return EOK;
+}
+
+fdisk_part_t *fdisk_part_first(fdisk_dev_t *dev)
+{
+	return NULL;
+}
+
+fdisk_part_t *fdisk_part_next(fdisk_part_t *part)
+{
+	return NULL;
+}
+
+int fdisk_part_get_max_avail(fdisk_dev_t *dev, fdisk_cap_t *cap)
+{
+	return EOK;
+}
+
+int fdisk_part_create(fdisk_dev_t *dev, fdisk_partspec_t *pspec,
+    fdisk_part_t **rpart)
+{
+	return EOK;
+}
+
+int fdisk_part_destroy(fdisk_part_t *part)
+{
+	return EOK;
+}
+
+int fdisk_cap_format(fdisk_cap_t *cap, char **rstr)
+{
+	int rc;
+
+	rc = asprintf(rstr, "%" PRIu64 " B", cap->value);
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
+int fdisk_ltype_format(fdisk_label_type_t ltype, char **rstr)
+{
+	const char *sltype;
+	char *s;
+
+	sltype = NULL;
+	switch (ltype) {
+	case fdl_none:
+		sltype = "None";
+		break;
+	case fdl_unknown:
+		sltype = "Unknown";
+		break;
+	case fdl_mbr:
+		sltype = "MBR";
+		break;
+	case fdl_gpt:
+		sltype = "GPT";
+		break;
+	}
+
+	s = str_dup(sltype);
+	if (s == NULL)
+		return ENOMEM;
+
+	*rstr = s;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision 2654afbde2adc86cb19dddeb6edeb7ad9308db21)
+++ uspace/srv/locsrv/locsrv.c	(revision e96047c95e2e340c70836a813474717696c06c3e)
@@ -1325,4 +1325,7 @@
 	categ_dir_add_cat(&cdir, cat);
 
+	cat = category_new("disk");
+	categ_dir_add_cat(&cdir, cat);
+
 	cat = category_new("iplink");
 	categ_dir_add_cat(&cdir, cat);
