Index: uspace/srv/sysman/job.c
===================================================================
--- uspace/srv/sysman/job.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
+++ uspace/srv/sysman/job.c	(revision c0c388d236382891ee84310636e6cab9af0f510c)
@@ -14,4 +14,7 @@
 static fibril_condvar_t job_queue_cv;
 
+static void job_destroy(job_t **);
+
+
 static int job_run_start(job_t *job)
 {
@@ -72,4 +75,6 @@
 	fibril_condvar_broadcast(&job->state_cv);
 	fibril_mutex_unlock(&job->state_mtx);
+
+	job_del_ref(&job);
 
 	return EOK;
@@ -91,8 +96,8 @@
 		 * 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.
+		 * circular dependency between jobs, it may result in 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*?
+		fid_t runner_fibril = fibril_create(job_runner, job);
 		fibril_add_ready(runner_fibril);
 	}
@@ -135,4 +140,5 @@
 	}
 
+	/* Only job dispatcher waits, it's correct to notify one only. */
 	fibril_condvar_signal(&job_queue_cv);
 	fibril_mutex_unlock(&job_queue_mtx);
@@ -160,4 +166,22 @@
 }
 
+void job_add_ref(job_t *job)
+{
+	atomic_inc(&job->refcnt);
+}
+
+void job_del_ref(job_t **job_ptr)
+{
+	job_t *job = *job_ptr;
+	if (job == NULL) {
+		return;
+	}
+
+	assert(atomic_get(&job->refcnt) > 0);
+	if (atomic_predec(&job->refcnt) == 0) {
+		job_destroy(job_ptr);
+	}
+}
+
 static void job_init(job_t *job, job_type_t type)
 {
@@ -166,4 +190,7 @@
 	link_initialize(&job->link);
 	list_initialize(&job->blocking_jobs);
+
+	/* Start with one reference for the creator */
+	atomic_set(&job->refcnt, 1);
 
 	job->type = type;
@@ -185,5 +212,5 @@
 }
 
-void job_destroy(job_t **job_ptr)
+static void job_destroy(job_t **job_ptr)
 {
 	job_t *job = *job_ptr;
@@ -195,4 +222,5 @@
 		job_link_t *jl = list_get_instance(cur_link, job_link_t, link);
 		list_remove(cur_link);
+		job_del_ref(&jl->job);
 		free(jl);
 	}
Index: uspace/srv/sysman/job.h
===================================================================
--- uspace/srv/sysman/job.h	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
+++ uspace/srv/sysman/job.h	(revision c0c388d236382891ee84310636e6cab9af0f510c)
@@ -3,4 +3,5 @@
 
 #include <adt/list.h>
+#include <atomic.h>
 
 #include "unit.h"
@@ -25,7 +26,12 @@
 
 struct job {
+	/** Link to queue job is in */
 	link_t link;
 
+	/** List of jobs (job_link_t ) that are blocking the job. */
 	list_t blocking_jobs;
+
+	/** Reference counter for the job structure. */
+	atomic_t refcnt;
 
 	job_type_t type;
@@ -36,4 +42,5 @@
 	fibril_condvar_t state_cv;
 
+	/** Return value of the job, defined only when state == JOB_FINISHED */
 	int retval;
 };
@@ -44,6 +51,8 @@
 extern int job_wait(job_t *);
 
+extern void job_add_ref(job_t *);
+extern void job_del_ref(job_t **);
+
 extern job_t *job_create(job_type_t type);
-extern void job_destroy(job_t **);
 
 #endif
Index: uspace/srv/sysman/sysman.c
===================================================================
--- uspace/srv/sysman/sysman.c	(revision 694253c27e8751a752fc1370b3d5f3087fe1ba11)
+++ uspace/srv/sysman/sysman.c	(revision c0c388d236382891ee84310636e6cab9af0f510c)
@@ -27,4 +27,5 @@
 	}
 
+	/* Job is passed to the accumulator, i.e. no add_ref. */
 	list_append(&job->link, accumulator);
 
@@ -35,5 +36,5 @@
 
 fail:
-	job_destroy(&job);
+	job_del_ref(&job);
 	return rc;
 }
@@ -50,4 +51,5 @@
 	}
 
+	// TODO handle errors when adding job accumulator
 	job_queue_jobs(&new_jobs);
 
