Index: uspace/srv/sysman/Makefile
===================================================================
--- uspace/srv/sysman/Makefile	(revision f42ee6f303b03f563ca4bf42301c737e9efa2172)
+++ uspace/srv/sysman/Makefile	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -35,4 +35,5 @@
 	configuration.c \
 	dep.c \
+	job.c \
 	main.c \
 	sysman.c \
Index: uspace/srv/sysman/dep.c
===================================================================
--- uspace/srv/sysman/dep.c	(revision f42ee6f303b03f563ca4bf42301c737e9efa2172)
+++ uspace/srv/sysman/dep.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -10,12 +10,14 @@
 int dep_add_dependency(unit_t *dependant, unit_t *dependency)
 {
-	unit_dependency_t *edge = malloc(sizeof(unit_t));
+	unit_dependency_t *edge = malloc(sizeof(unit_dependency_t));
 	if (edge == NULL) {
 		return ENOMEM;
 	}
+	link_initialize(&edge->dependants);
+	link_initialize(&edge->dependencies);
+
 	// TODO check existence of the edge
 	// TODO locking
 	// TODO check types and states of connected units
-	/* Do not initalize links as they are immediately inserted into list */
 	list_append(&edge->dependants, &dependency->dependants);
 	list_append(&edge->dependencies, &dependant->dependencies);
Index: uspace/srv/sysman/job.c
===================================================================
--- uspace/srv/sysman/job.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
+++ uspace/srv/sysman/job.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -0,0 +1,202 @@
+#include <adt/list.h>
+#include <assert.h>
+#include <errno.h>
+#include <fibril.h>
+#include <fibril_synch.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "job.h"
+#include "unit.h"
+
+static list_t job_queue;
+static fibril_mutex_t job_queue_mtx;
+static fibril_condvar_t job_queue_cv;
+
+static int job_run_start(job_t *job)
+{
+	unit_t *unit = job->unit;
+
+	int rc = unit_start(unit);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	fibril_mutex_lock(&unit->state_mtx);
+	while (unit->state != STATE_STARTED) {
+		fibril_condvar_wait(&unit->state_cv, &unit->state_mtx);
+	}
+	fibril_mutex_unlock(&unit->state_mtx);
+
+	// TODO react to failed state
+	return EOK;
+}
+
+static int job_runner(void *arg)
+{
+	job_t *job = (job_t *)arg;
+
+	int retval = EOK;
+
+	/* Wait for previous jobs */
+	list_foreach(job->blocking_jobs, link, job_link_t, jl) {
+		retval = job_wait(jl->job);
+		if (retval != EOK) {
+			break;
+		}
+	}
+
+	if (retval != EOK) {
+		goto finish;
+	}
+
+	/* Run the job itself */
+	fibril_mutex_lock(&job->state_mtx);
+	job->state = JOB_RUNNING;
+	fibril_condvar_broadcast(&job->state_cv);
+	fibril_mutex_unlock(&job->state_mtx);
+
+	switch (job->type) {
+	case JOB_START:
+		retval = job_run_start(job);
+		break;
+	default:
+		assert(false);
+	}
+
+
+finish:
+	fibril_mutex_lock(&job->state_mtx);
+	job->state = JOB_FINISHED;
+	job->retval = retval;
+	fibril_condvar_broadcast(&job->state_cv);
+	fibril_mutex_unlock(&job->state_mtx);
+
+	return EOK;
+}
+
+static int job_dispatcher(void *arg)
+{
+	fibril_mutex_lock(&job_queue_mtx);
+	while (1) {
+		while (list_empty(&job_queue)) {
+			fibril_condvar_wait(&job_queue_cv, &job_queue_mtx);
+		}
+		
+		link_t *link = list_first(&job_queue);
+		assert(link);
+		list_remove(link);
+
+		/*
+		 * Note that possible use of fibril pool must hold invariant
+		 * that job is started asynchronously. In the case there exists
+		 * circular dependency between jobs, it may attain a deadlock.
+		 */
+		job_t *job = list_get_instance(link, job_t, link);
+		fid_t runner_fibril = fibril_create(job_runner, job); // TODO cast to void*?
+		fibril_add_ready(runner_fibril);
+	}
+
+	fibril_mutex_unlock(&job_queue_mtx);
+	return EOK;
+}
+
+void job_queue_init()
+{
+	list_initialize(&job_queue);
+	fibril_mutex_initialize(&job_queue_mtx);
+	fibril_condvar_initialize(&job_queue_cv);
+
+	fid_t dispatcher_fibril = fibril_create(job_dispatcher, NULL);
+	fibril_add_ready(dispatcher_fibril);
+}
+
+int job_queue_jobs(list_t *jobs)
+{
+	fibril_mutex_lock(&job_queue_mtx);
+
+	/* Check consistency with queue. */
+	list_foreach(*jobs, link, job_t, new_job) {
+		list_foreach(job_queue, link, job_t, queued_job) {
+			/*
+			 * Currently we have strict strategy not permitting
+			 * multiple jobs for one unit in the queue.
+			 */
+			if (new_job->unit == queued_job->unit) {
+				return EEXIST;
+			}
+		}
+	}
+
+	/* Enqueue jobs */
+	list_foreach_safe(*jobs, cur_link, next_lin) {
+		list_remove(cur_link);
+		list_append(cur_link, &job_queue);
+	}
+
+	fibril_condvar_signal(&job_queue_cv);
+	fibril_mutex_unlock(&job_queue_mtx);
+
+	return EOK;
+}
+
+/** Blocking wait for job finishing.
+ *
+ * Multiple fibrils may wait for the same job.
+ *
+ * @return    Return code of the job
+ */
+int job_wait(job_t *job)
+{
+	fibril_mutex_lock(&job->state_mtx);
+	while (job->state != JOB_FINISHED) {
+		fibril_condvar_wait(&job->state_cv, &job->state_mtx);
+	}
+
+	int rc = job->retval;
+	fibril_mutex_unlock(&job->state_mtx);
+
+	return rc;
+}
+
+static void job_init(job_t *job, job_type_t type)
+{
+	assert(job);
+
+	link_initialize(&job->link);
+	list_initialize(&job->blocking_jobs);
+
+	job->type = type;
+	job->unit = NULL;
+
+	job->state = JOB_WAITING;
+	fibril_mutex_initialize(&job->state_mtx);
+	fibril_condvar_initialize(&job->state_cv);
+}
+
+job_t *job_create(job_type_t type)
+{
+	job_t *job = malloc(sizeof(job_t));
+	if (job != NULL) {
+		job_init(job, type);
+	}
+
+	return job;
+}
+
+void job_destroy(job_t **job_ptr)
+{
+	job_t *job = *job_ptr;
+	if (job == NULL) {
+		return;
+	}
+
+	list_foreach_safe(job->blocking_jobs, cur_link, next_link) {
+		job_link_t *jl = list_get_instance(cur_link, job_link_t, link);
+		list_remove(cur_link);
+		free(jl);
+	}
+	free(job);
+
+	*job_ptr = NULL;
+}
Index: uspace/srv/sysman/job.h
===================================================================
--- uspace/srv/sysman/job.h	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
+++ uspace/srv/sysman/job.h	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -0,0 +1,49 @@
+#ifndef SYSMAN_JOB_H
+#define SYSMAN_JOB_H
+
+#include <adt/list.h>
+
+#include "unit.h"
+
+struct job;
+typedef struct job job_t;
+
+typedef enum {
+	JOB_START
+} job_type_t;
+
+typedef enum {
+	JOB_WAITING,
+	JOB_RUNNING,
+	JOB_FINISHED
+} job_state_t;
+
+typedef struct {
+	link_t link;
+	job_t *job;
+} job_link_t;
+
+struct job {
+	link_t link;
+
+	list_t blocking_jobs;
+
+	job_type_t type;
+	unit_t *unit;
+
+	job_state_t state;
+	fibril_mutex_t state_mtx;
+	fibril_condvar_t state_cv;
+
+	int retval;
+};
+
+extern void job_queue_init(void);
+extern int job_queue_jobs(list_t *);
+
+extern int job_wait(job_t *);
+
+extern job_t *job_create(job_type_t type);
+extern void job_destroy(job_t **);
+
+#endif
Index: uspace/srv/sysman/main.c
===================================================================
--- uspace/srv/sysman/main.c	(revision f42ee6f303b03f563ca4bf42301c737e9efa2172)
+++ uspace/srv/sysman/main.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -7,4 +7,5 @@
 #include "configuration.h"
 #include "dep.h"
+#include "job.h"
 #include "sysman.h"
 #include "unit.h"
@@ -85,4 +86,5 @@
 
 	configuration_init();
+	job_queue_init();
 
 	/*
Index: uspace/srv/sysman/sysman.c
===================================================================
--- uspace/srv/sysman/sysman.c	(revision f42ee6f303b03f563ca4bf42301c737e9efa2172)
+++ uspace/srv/sysman/sysman.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -1,10 +1,55 @@
+#include <adt/list.h>
 #include <errno.h>
 
+#include "dep.h"
+#include "job.h"
 #include "sysman.h"
+
+static int sysman_create_closure_jobs(unit_t *unit, job_t **entry_job_ptr,
+    list_t *accumulator, job_type_t type)
+{
+	int rc = EOK;
+	job_t *job = job_create(type);
+	if (job == NULL) {
+		rc = ENOMEM;
+		goto fail;
+	}
+
+	job->unit = unit;
+	// TODO set blocking jobs
+
+	list_foreach(unit->dependencies, dependencies, unit_dependency_t, edge) {
+		rc = sysman_create_closure_jobs(edge->dependency, NULL,
+		    accumulator, type);
+		if (rc != EOK) {
+			goto fail;
+		}
+	}
+
+	list_append(&job->link, accumulator);
+
+	if (entry_job_ptr != NULL) {
+		*entry_job_ptr = job;
+	}
+	return EOK;
+
+fail:
+	job_destroy(&job);
+	return rc;
+}
 
 int sysman_unit_start(unit_t *unit)
 {
-	// satisfy dependencies
-	// start unit (via restarter)
-	return EOK;
+	list_t new_jobs;
+	list_initialize(&new_jobs);
+
+	job_t *job = NULL;
+	int rc = sysman_create_closure_jobs(unit, &job, &new_jobs, JOB_START);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	job_queue_jobs(&new_jobs);
+
+	return job_wait(job);
 }
Index: uspace/srv/sysman/unit.c
===================================================================
--- uspace/srv/sysman/unit.c	(revision f42ee6f303b03f563ca4bf42301c737e9efa2172)
+++ uspace/srv/sysman/unit.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -1,4 +1,7 @@
 #include <assert.h>
+#include <errno.h>
+#include <fibril_synch.h>
 #include <mem.h>
+#include <stdio.h>
 #include <stdlib.h>
 
@@ -9,12 +12,13 @@
 	assert(unit);
 
-	memset(unit, 0, sizeof(unit));
+	link_initialize(&unit->units);
+	
+	unit->type = type;
+	unit->state = STATE_EMBRYO;
+	fibril_mutex_initialize(&unit->state_mtx);
+	fibril_condvar_initialize(&unit->state_cv);
 
-	link_initialize(&unit->units);
 	list_initialize(&unit->dependants);
 	list_initialize(&unit->dependencies);
-
-	unit->type = type;
-	unit->state = STATE_EMBRYO;
 }
 
@@ -42,2 +46,14 @@
 	*unit = NULL;
 }
+
+/** Issue request to restarter to start a unit
+ *
+ * Return from this function only means start request was issued.
+ * If you need to wait for real start of the unit, use waiting on state_cv.
+ */
+int unit_start(unit_t *unit)
+{
+	// TODO actually start the unit
+	printf("Starting unit of type %i\n", unit->type);
+	return EOK;
+}
Index: uspace/srv/sysman/unit.h
===================================================================
--- uspace/srv/sysman/unit.h	(revision f42ee6f303b03f563ca4bf42301c737e9efa2172)
+++ uspace/srv/sysman/unit.h	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
@@ -3,4 +3,5 @@
 
 #include <adt/list.h>
+#include <fibril_synch.h>
 
 #include "unit_mnt.h"
@@ -15,4 +16,5 @@
 typedef enum {
 	STATE_EMBRYO = 0,
+	STATE_STARTED,
 	STATE_STOPPED
 } unit_state_t;
@@ -22,5 +24,8 @@
 
 	unit_type_t type;
+
 	unit_state_t state;
+	fibril_mutex_t state_mtx;
+	fibril_condvar_t state_cv;
 
 	list_t dependencies;
@@ -37,4 +42,5 @@
 extern void unit_destroy(unit_t **);
 
+extern int unit_start(unit_t *);
 
 #endif
