Index: uspace/app/sysinst/sysinst.c
===================================================================
--- uspace/app/sysinst/sysinst.c	(revision 4b9213ddfddbd2707165d1dad24b14d20e8320fc)
+++ uspace/app/sysinst/sysinst.c	(revision 629b480c8129cdb6142f3771670d36a06e295b38)
@@ -73,4 +73,5 @@
 #define DEFAULT_DEV_0 "devices/\\hw\\sys\\00:01.1\\c0d0"
 #define DEFAULT_DEV_1 "devices/\\hw\\sys\\ide1\\c0d0"
+#define DEFAULT_DEV_2 "devices/\\hw\\sys\\00:01.0\\ide1\\c0d0"
 //#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0"
 /** Volume label for the new file system */
@@ -95,4 +96,5 @@
 	DEFAULT_DEV_0,
 	DEFAULT_DEV_1,
+	DEFAULT_DEV_2,
 	NULL
 };
@@ -155,4 +157,5 @@
 static void sysinst_futil_copy_file(void *, const char *, const char *);
 static void sysinst_futil_create_dir(void *, const char *);
+static errno_t sysinst_eject_dev(sysinst_t *, service_id_t);
 
 static futil_cb_t sysinst_futil_cb = {
@@ -424,5 +427,5 @@
 }
 
-/** Label the destination device.
+/** Label and mount the destination device.
  *
  * @param sysinst System installer
@@ -432,12 +435,13 @@
  * @return EOK on success or an error code
  */
-static errno_t sysinst_label_dev(sysinst_t *sysinst, const char *dev,
-    service_id_t *psvc_id)
-{
-	fdisk_t *fdisk;
-	fdisk_dev_t *fdev;
+static errno_t sysinst_label_dev(sysinst_t *sysinst, const char *dev)
+{
+	fdisk_t *fdisk = NULL;
+	fdisk_dev_t *fdev = NULL;
 	fdisk_part_t *part;
 	fdisk_part_spec_t pspec;
 	fdisk_part_info_t pinfo;
+	bool dir_created = false;
+	bool label_created = false;
 	capa_spec_t capa;
 	service_id_t sid;
@@ -448,5 +452,5 @@
 	rc = loc_service_get_id(dev, &sid, 0);
 	if (rc != EOK)
-		return rc;
+		goto error;
 
 	sysinst_debug(sysinst, "sysinst_label_dev(): open device");
@@ -455,5 +459,5 @@
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error initializing fdisk.");
-		return rc;
+		goto error;
 	}
 
@@ -461,5 +465,5 @@
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error opening device.");
-		return rc;
+		goto error;
 	}
 
@@ -469,6 +473,8 @@
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error creating mount directory.");
-		return rc;
-	}
+		goto error;
+	}
+
+	dir_created = true;
 
 	sysinst_debug(sysinst, "sysinst_label_dev(): create label");
@@ -477,6 +483,8 @@
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error creating label.");
-		return rc;
-	}
+		goto error;
+	}
+
+	label_created = true;
 
 	sysinst_debug(sysinst, "sysinst_label_dev(): create partition");
@@ -486,5 +494,5 @@
 		sysinst_error(sysinst,
 		    "Error getting available capacity.");
-		return rc;
+		goto error;
 	}
 
@@ -499,5 +507,5 @@
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error creating partition.");
-		return rc;
+		goto error;
 	}
 
@@ -505,9 +513,43 @@
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error getting partition information.");
-		return rc;
+		goto error;
 	}
 
 	sysinst_debug(sysinst, "sysinst_label_dev(): OK");
-	*psvc_id = pinfo.svc_id;
+	fdisk_dev_close(fdev);
+	fdisk_destroy(fdisk);
+	sysinst->psvc_id = pinfo.svc_id;
+	return EOK;
+error:
+	if (label_created)
+		fdisk_label_destroy(fdev);
+	if (dir_created)
+		(void)vfs_unlink_path(MOUNT_POINT);
+	if (fdev != NULL)
+		fdisk_dev_close(fdev);
+	if (fdisk != NULL)
+		fdisk_destroy(fdisk);
+	return rc;
+}
+
+/** Finish/unmount destination device.
+ *
+ * @param sysinst System installer
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t sysinst_finish_dev(sysinst_t *sysinst)
+{
+	errno_t rc;
+
+	sysinst_debug(sysinst, "sysinst_finish_dev(): eject target volume");
+	rc = sysinst_eject_dev(sysinst, sysinst->psvc_id);
+	if (rc != EOK)
+		return rc;
+
+	sysinst_debug(sysinst, "sysinst_finish_dev(): "
+	    "deleting mount directory");
+	(void)vfs_unlink_path(MOUNT_POINT);
+
 	return EOK;
 }
@@ -811,5 +853,5 @@
  *
  * @param sysinst System installer
- * @param psvc_id Partition service ID
+ * @param part_id Partition service ID
  * @return EOK on success or an error code
  */
@@ -825,5 +867,5 @@
 	}
 
-	rc = vol_part_eject(vol, part_id, vef_physical);
+	rc = vol_part_eject(vol, part_id, vef_none);
 	if (rc != EOK) {
 		sysinst_error(sysinst, "Error ejecting volume.");
@@ -837,4 +879,44 @@
 }
 
+/** Physically eject volume by mount point.
+ *
+ * @param sysinst System installer
+ * @param path Mount point
+ * @return EOK on success or an error code
+ */
+static errno_t sysinst_eject_phys_by_mp(sysinst_t *sysinst, const char *path)
+{
+	vol_t *vol = NULL;
+	sysarg_t part_id;
+	errno_t rc;
+
+	rc = vol_create(&vol);
+	if (rc != EOK) {
+		sysinst_error(sysinst, "Error contacting volume service.");
+		goto out;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_by_mp: mp='%s'\n",
+	    path);
+	rc = vol_part_by_mp(vol, path, &part_id);
+	if (rc != EOK) {
+		sysinst_error(sysinst,
+		    "Error finding installation media mount point.");
+		goto out;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "eject svc_id %lu", (unsigned long)part_id);
+	rc = vol_part_eject(vol, part_id, vef_physical);
+	if (rc != EOK) {
+		sysinst_error(sysinst, "Error ejecting volume.");
+		goto out;
+	}
+
+	rc = EOK;
+out:
+	vol_destroy(vol);
+	return rc;
+}
+
 /** Restart the system.
  *
@@ -901,9 +983,8 @@
 {
 	errno_t rc;
-	service_id_t psvc_id;
 
 	sysinst_action(sysinst, "Creating device label and file system.");
 
-	rc = sysinst_label_dev(sysinst, dev, &psvc_id);
+	rc = sysinst_label_dev(sysinst, dev);
 	if (rc != EOK)
 		return rc;
@@ -924,4 +1005,9 @@
 		return rc;
 
+	sysinst_action(sysinst, "Finishing system volume.");
+	rc = sysinst_finish_dev(sysinst);
+	if (rc != EOK)
+		return rc;
+
 	sysinst_action(sysinst, "Installing boot blocks.");
 	rc = sysinst_copy_boot_blocks(sysinst, dev);
@@ -929,6 +1015,6 @@
 		return rc;
 
-	sysinst_action(sysinst, "Ejecting device.");
-	rc = sysinst_eject_dev(sysinst, psvc_id);
+	sysinst_action(sysinst, "Ejecting installation media.");
+	rc = sysinst_eject_phys_by_mp(sysinst, CD_MOUNT_POINT);
 	if (rc != EOK)
 		return rc;
Index: uspace/app/sysinst/sysinst.h
===================================================================
--- uspace/app/sysinst/sysinst.h	(revision 4b9213ddfddbd2707165d1dad24b14d20e8320fc)
+++ uspace/app/sysinst/sysinst.h	(revision 629b480c8129cdb6142f3771670d36a06e295b38)
@@ -39,4 +39,5 @@
 #include <futil.h>
 #include <gfx/color.h>
+#include <loc.h>
 #include <system.h>
 #include <ui/fixed.h>
@@ -60,4 +61,6 @@
 	sysinst_progress_t *progress;
 	system_t *system;
+	/** Service ID of destination partition. */
+	sysarg_t psvc_id;
 	futil_t *futil;
 	char errmsg[128];
Index: uspace/app/vol/vol.c
===================================================================
--- uspace/app/vol/vol.c	(revision 4b9213ddfddbd2707165d1dad24b14d20e8320fc)
+++ uspace/app/vol/vol.c	(revision 629b480c8129cdb6142f3771670d36a06e295b38)
@@ -54,58 +54,4 @@
 } vol_cmd_t;
 
-/** Find volume by current mount point. */
-static errno_t vol_cmd_part_by_mp(vol_t *vol, const char *mp,
-    service_id_t *rid)
-{
-	vol_part_info_t vinfo;
-	service_id_t *part_ids = NULL;
-	char *canon_mp_buf = NULL;
-	char *canon_mp;
-	size_t nparts;
-	size_t i;
-	errno_t rc;
-
-	canon_mp_buf = str_dup(mp);
-	if (canon_mp_buf == NULL) {
-		printf("Out of memory.\n");
-		rc = ENOMEM;
-		goto out;
-	}
-
-	canon_mp = vfs_absolutize(canon_mp_buf, NULL);
-	if (canon_mp == NULL) {
-		printf("Invalid volume path '%s'.\n", mp);
-		rc = EINVAL;
-		goto out;
-	}
-
-	rc = vol_get_parts(vol, &part_ids, &nparts);
-	if (rc != EOK) {
-		printf("Error getting list of volumes.\n");
-		goto out;
-	}
-
-	for (i = 0; i < nparts; i++) {
-		rc = vol_part_info(vol, part_ids[i], &vinfo);
-		if (rc != EOK) {
-			printf("Error getting volume information.\n");
-			rc = EIO;
-			goto out;
-		}
-
-		if (str_cmp(vinfo.cur_mp, canon_mp) == 0) {
-			*rid = part_ids[i];
-			rc = EOK;
-			goto out;
-		}
-	}
-
-	rc = ENOENT;
-out:
-	free(part_ids);
-	free(canon_mp_buf);
-	return rc;
-}
-
 static errno_t vol_cmd_eject(const char *volspec, bool physical)
 {
@@ -120,5 +66,5 @@
 	}
 
-	rc = vol_cmd_part_by_mp(vol, volspec, &part_id);
+	rc = vol_part_by_mp(vol, volspec, &part_id);
 	if (rc != EOK) {
 		printf("Error looking up volume '%s'.\n", volspec);
Index: uspace/lib/device/include/vol.h
===================================================================
--- uspace/lib/device/include/vol.h	(revision 4b9213ddfddbd2707165d1dad24b14d20e8320fc)
+++ uspace/lib/device/include/vol.h	(revision 629b480c8129cdb6142f3771670d36a06e295b38)
@@ -61,4 +61,5 @@
 extern errno_t vol_pcnt_fs_format(vol_part_cnt_t, vol_fstype_t, char **);
 extern errno_t vol_mountp_validate(const char *);
+extern errno_t vol_part_by_mp(vol_t *, const char *, service_id_t *);
 
 #endif
Index: uspace/lib/device/src/vol.c
===================================================================
--- uspace/lib/device/src/vol.c	(revision 4b9213ddfddbd2707165d1dad24b14d20e8320fc)
+++ uspace/lib/device/src/vol.c	(revision 629b480c8129cdb6142f3771670d36a06e295b38)
@@ -608,4 +608,58 @@
 }
 
+/** Find volume by current mount point.
+ *
+ * @param vol Volume service
+ * @param mp Mount point
+ * @param rid Place to store partition service ID
+ * @return EOK on success or an error code
+ */
+errno_t vol_part_by_mp(vol_t *vol, const char *mp, service_id_t *rid)
+{
+	vol_part_info_t vinfo;
+	service_id_t *part_ids = NULL;
+	char *canon_mp_buf = NULL;
+	char *canon_mp;
+	size_t nparts;
+	size_t i;
+	errno_t rc;
+
+	canon_mp_buf = str_dup(mp);
+	if (canon_mp_buf == NULL) {
+		rc = ENOMEM;
+		goto out;
+	}
+
+	canon_mp = vfs_absolutize(canon_mp_buf, NULL);
+	if (canon_mp == NULL) {
+		rc = EINVAL;
+		goto out;
+	}
+
+	rc = vol_get_parts(vol, &part_ids, &nparts);
+	if (rc != EOK)
+		goto out;
+
+	for (i = 0; i < nparts; i++) {
+		rc = vol_part_info(vol, part_ids[i], &vinfo);
+		if (rc != EOK) {
+			rc = EIO;
+			goto out;
+		}
+
+		if (str_cmp(vinfo.cur_mp, canon_mp) == 0) {
+			*rid = part_ids[i];
+			rc = EOK;
+			goto out;
+		}
+	}
+
+	rc = ENOENT;
+out:
+	free(part_ids);
+	free(canon_mp_buf);
+	return rc;
+}
+
 /** @}
  */
Index: uspace/lib/futil/src/futil.c
===================================================================
--- uspace/lib/futil/src/futil.c	(revision 4b9213ddfddbd2707165d1dad24b14d20e8320fc)
+++ uspace/lib/futil/src/futil.c	(revision 629b480c8129cdb6142f3771670d36a06e295b38)
@@ -99,7 +99,10 @@
 		return EIO;
 
-	rc = vfs_lookup_open(destp, WALK_REGULAR | WALK_MAY_CREATE, MODE_WRITE, &df);
-	if (rc != EOK)
-		return EIO;
+	rc = vfs_lookup_open(destp, WALK_REGULAR | WALK_MAY_CREATE, MODE_WRITE,
+	    &df);
+	if (rc != EOK) {
+		vfs_put(sf);
+		return EIO;
+	}
 
 	do {
@@ -152,17 +155,24 @@
 	de = readdir(dir);
 	while (de != NULL) {
-		if (asprintf(&srcp, "%s/%s", srcdir, de->d_name) < 0)
-			return ENOMEM;
-		if (asprintf(&destp, "%s/%s", destdir, de->d_name) < 0)
-			return ENOMEM;
+		if (asprintf(&srcp, "%s/%s", srcdir, de->d_name) < 0) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		if (asprintf(&destp, "%s/%s", destdir, de->d_name) < 0) {
+			rc = ENOMEM;
+			goto error;
+		}
 
 		rc = vfs_stat_path(srcp, &s);
 		if (rc != EOK)
-			return EIO;
+			goto error;
 
 		if (s.is_file) {
 			rc = futil_copy_file(futil, srcp, destp);
-			if (rc != EOK)
-				return EIO;
+			if (rc != EOK) {
+				rc = EIO;
+				goto error;
+			}
 		} else if (s.is_directory) {
 			if (futil->cb != NULL && futil->cb->create_dir != NULL)
@@ -170,10 +180,11 @@
 			rc = vfs_link_path(destp, KIND_DIRECTORY, NULL);
 			if (rc != EOK)
-				return EIO;
+				goto error;
 			rc = futil_rcopy_contents(futil, srcp, destp);
 			if (rc != EOK)
-				return EIO;
+				goto error;
 		} else {
-			return EIO;
+			rc = EIO;
+			goto error;
 		}
 
@@ -181,5 +192,9 @@
 	}
 
-	return EOK;
+	closedir(dir);
+	return EOK;
+error:
+	closedir(dir);
+	return rc;
 }
 
