Index: uspace/srv/sysman/job_closure.c
===================================================================
--- uspace/srv/sysman/job_closure.c	(revision 015b147d9719aa8732f3b739eb43489e1d44f708)
+++ uspace/srv/sysman/job_closure.c	(revision be07995661547b856a461a29a94ec0fbbb5a8fb0)
@@ -82,5 +82,6 @@
 /** During visit creates job and appends it to closure
  *
- * @note Assumes BFS start unit's job is already present in closure!
+ * @note Assumes BFS origin unit's job is already present in the closure on the
+ *       last position!
  *
  * @return EOK on success
@@ -94,5 +95,7 @@
 
 	if (e == NULL) {
-		assert(u->bfs_data == NULL);
+		if (u->bfs_data != NULL) {
+			goto finish;
+		}
 		job_t *first_job = dyn_array_last(closure, job_t *);
 
@@ -133,4 +136,46 @@
 		job_del_ref(&created_job);
 	}
+	return rc;
+}
+
+static int visit_isolate(unit_t *u, unit_edge_t *e, bfs_ops_t *ops, void *arg)
+{
+	int rc = EOK;
+	job_t *created_job = NULL;
+	job_closure_t *closure = arg;
+
+	sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(u));
+	/*
+	 * Unit can have starting job from original request or from isolation
+	 * BFS with different origin.
+	 *
+	 * Don't check u->state == STATE_STOPPED, closure is created stateless
+	 * and its upon merging procedure to correctly resolve conflicting
+	 * jobs.
+	 *
+	 * If we're at the origin (no BFS incoming edge), create a stop job,
+	 * put it to the closure and let propagate as if called the propagate
+	 * visitor.
+	 */
+	if (e == NULL && u->bfs_data == NULL) {
+		created_job = job_create(u, STATE_STOPPED);
+		if (created_job == NULL) {
+			rc = ENOMEM;
+			goto finish;
+		}
+
+		/* Pass job reference to closure and add one for unit */
+		rc = dyn_array_append(closure, job_t *, created_job);
+		if (rc != EOK) {
+			goto finish;
+		}
+	}
+	rc = visit_propagate_job(u, e, ops, closure);
+
+finish:
+	if (rc != EOK) {
+		job_del_ref(&created_job);
+	}
+	sysman_log(LVL_DEBUG2, "%s(%s) -> %i", __func__, unit_name(u), rc);
 	return rc;
 }
@@ -217,6 +262,30 @@
 }
 
-// TODO bfs_traverse_all
-
+static int bfs_traverse_all(bfs_ops_t *ops, void *arg)
+{
+	/* Check invariant */
+	repo_foreach(u) {
+		assert(u->bfs_tag == false);
+	}
+	int rc = EOK;
+
+	repo_foreach(origin) {
+		sysman_log(LVL_DEBUG2, "%s: %p, %i", __func__, origin, origin->bfs_tag);
+		if (origin->bfs_tag == true) {
+			continue;
+		}
+		rc = bfs_traverse_component_internal(origin, ops, arg);
+		if (rc != EOK) {
+			goto finish;
+		}
+	}
+
+finish:
+	/* Clean after ourselves (BFS tag jobs) */
+	repo_foreach(u) {
+		u->bfs_tag = false;
+	}
+	return rc;
+}
 
 /*
@@ -230,19 +299,30 @@
  * @return EOK on success otherwise propagated error
  */
-int job_create_closure(job_t *main_job, job_closure_t *job_closure)
+int job_create_closure(job_t *main_job, job_closure_t *job_closure, int flags)
 {
 	sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(main_job->unit));
 
-	static bfs_ops_t ops = {
+	if ((flags & CLOSURE_ISOLATE) && main_job->target_state != STATE_STARTED) {
+		// TODO EINVAL?
+		return ENOTSUP;
+	}
+
+	int rc = dyn_array_append(job_closure, job_t *, main_job);
+	if (rc != EOK) {
+		return rc;
+	}
+	job_add_ref(main_job); /* Add one for the closure */
+
+	/* Propagate main_job to other (dependent) units */
+	static bfs_ops_t propagate_ops = {
 		.clean = traverse_clean,
 		.visit = visit_propagate_job
 	};
-
 	switch (main_job->target_state) {
 	case STATE_STARTED:
-		ops.direction = BFS_FORWARD;
+		propagate_ops.direction = BFS_FORWARD;
 		break;
 	case STATE_STOPPED:
-		ops.direction = BFS_BACKWARD;
+		propagate_ops.direction = BFS_BACKWARD;
 		break;
 	default:
@@ -250,14 +330,17 @@
 	}
 
-	int rc = dyn_array_append(job_closure, job_t *, main_job);
-	if (rc != EOK) {
-		return rc;
-	}
-	job_add_ref(main_job); /* Add one for the closure */
-
-	rc = bfs_traverse_component(main_job->unit, &ops, job_closure);
+	rc = bfs_traverse_component(main_job->unit, &propagate_ops, job_closure);
+
+	sysman_log(LVL_DEBUG2, "%s: %i&%i", __func__, flags, CLOSURE_ISOLATE);
+	if (flags & CLOSURE_ISOLATE) {
+		static bfs_ops_t isolate_ops = {
+			.direction = BFS_BACKWARD,
+			.clean = traverse_clean,
+			.visit = visit_isolate
+		};
+		rc = bfs_traverse_all(&isolate_ops, job_closure);
+	}
 
 	if (rc == EOK) {
-		sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit));
 		dyn_array_foreach(*job_closure, job_t *, job_it) {
 			sysman_log(LVL_DEBUG2, "%s\t%s, refs: %u", __func__,
Index: uspace/srv/sysman/job_closure.h
===================================================================
--- uspace/srv/sysman/job_closure.h	(revision 015b147d9719aa8732f3b739eb43489e1d44f708)
+++ uspace/srv/sysman/job_closure.h	(revision be07995661547b856a461a29a94ec0fbbb5a8fb0)
@@ -33,9 +33,10 @@
 
 #include "job.h"
-#include "unit.h"
+
+#define CLOSURE_ISOLATE 0x1
 
 typedef dyn_array_t job_closure_t;
 
-extern int job_create_closure(job_t *, job_closure_t *);
+extern int job_create_closure(job_t *, job_closure_t *, int);
 
 #endif
Index: uspace/srv/sysman/repo.c
===================================================================
--- uspace/srv/sysman/repo.c	(revision 015b147d9719aa8732f3b739eb43489e1d44f708)
+++ uspace/srv/sysman/repo.c	(revision be07995661547b856a461a29a94ec0fbbb5a8fb0)
@@ -176,5 +176,5 @@
 }
 
-void repo_begin_update_(void) {
+void repo_begin_update(void) {
 	sysman_log(LVL_DEBUG2, "%s", __func__);
 	fibril_rwlock_write_lock(&repo_lock);
@@ -293,5 +293,5 @@
  * The function can be safely called from non-event loop fibrils
  */
-unit_t *repo_find_unit_by_name_(const char *name)
+unit_t *repo_find_unit_by_name(const char *name)
 {
 	return repo_find_unit_by_name_internal(name, true);
Index: uspace/srv/sysman/sysman.c
===================================================================
--- uspace/srv/sysman/sysman.c	(revision 015b147d9719aa8732f3b739eb43489e1d44f708)
+++ uspace/srv/sysman/sysman.c	(revision be07995661547b856a461a29a94ec0fbbb5a8fb0)
@@ -373,5 +373,5 @@
 	free(job_args);
 
-	int rc = job_create_closure(job, &job_closure);
+	int rc = job_create_closure(job, &job_closure, 0);
 	if (rc != EOK) {
 		sysman_log(LVL_ERROR, "Cannot create closure for job %p (%i)",
Index: uspace/srv/sysman/test/job_closure.c
===================================================================
--- uspace/srv/sysman/test/job_closure.c	(revision 015b147d9719aa8732f3b739eb43489e1d44f708)
+++ uspace/srv/sysman/test/job_closure.c	(revision be07995661547b856a461a29a94ec0fbbb5a8fb0)
@@ -32,4 +32,5 @@
 
 #include "../job_closure.h"
+#include "../repo.h"
 
 #include "mock_unit.h"
@@ -50,6 +51,6 @@
 {
 	if (expected->size != actual->size) {
-		printf("%s: |expected| - |actual| = %u\n",
-		    __func__, expected->size - actual->size);
+		printf("%s: |expected|, |actual| = %u, %u\n",
+		    __func__, expected->size, actual->size);
 		return false;
 	}
@@ -119,4 +120,6 @@
 	rc = dyn_array_reserve(&act_closure, MAX_TYPES * MAX_UNITS);
 	assert(rc == EOK);
+
+	repo_init();
 }
 
@@ -148,5 +151,5 @@
 	assert(main_job);
 
-	int rc = job_create_closure(main_job, &act_closure);
+	int rc = job_create_closure(main_job, &act_closure, 0);
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
@@ -179,5 +182,5 @@
 	assert(main_job);
 
-	int rc = job_create_closure(main_job, &act_closure);
+	int rc = job_create_closure(main_job, &act_closure, 0);
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
@@ -212,5 +215,5 @@
 	assert(main_job);
 
-	int rc = job_create_closure(main_job, &act_closure);
+	int rc = job_create_closure(main_job, &act_closure, 0);
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
@@ -227,4 +230,57 @@
 }
 
+PCUT_TEST(job_closure_isolate_linears) {
+	unit_t *u0 = mock_units[UNIT_SERVICE][0];
+	unit_t *u1 = mock_units[UNIT_SERVICE][1];
+	unit_t *u2 = mock_units[UNIT_SERVICE][2];
+	unit_t *u3 = mock_units[UNIT_SERVICE][3];
+	unit_t *u4 = mock_units[UNIT_SERVICE][4];
+	unit_t *u5 = mock_units[UNIT_SERVICE][5];
+	unit_t *u6 = mock_units[UNIT_SERVICE][6];
+	repo_begin_update();
+	for (int i = 0; i < 7; ++i) {
+		repo_add_unit(mock_units[UNIT_SERVICE][i]);
+	}
+	repo_commit();
+
+	/*
+	 *
+	 * u0 -> u1 -> u2
+	 *
+	 * u3 -> u4 -> u5
+	 *
+	 * u6
+	 */
+	mock_add_edge(u0, u1);
+	mock_add_edge(u1, u2);
+
+	mock_add_edge(u3, u4);
+	mock_add_edge(u4, u5);
+
+	job_t *main_job = job_create(u1, STATE_STARTED);
+	assert(main_job);
+
+	int rc = job_create_closure(main_job, &act_closure, CLOSURE_ISOLATE);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u0, STATE_STOPPED));
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u1, STATE_STARTED));
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u2, STATE_STARTED));
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u3, STATE_STOPPED));
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u4, STATE_STOPPED));
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u5, STATE_STOPPED));
+	dyn_array_append(&exp_closure, job_t *, dummy_job(u6, STATE_STOPPED));
+
+	dummy_add_closure(&act_closure);
+
+	PCUT_ASSERT_TRUE(same_jobs(&exp_closure, &act_closure));
+	PCUT_ASSERT_TRUE(job_blocked(u1->job, u2->job));
+
+	PCUT_ASSERT_TRUE(job_blocked(u5->job, u4->job));
+	PCUT_ASSERT_TRUE(job_blocked(u4->job, u3->job));
+
+	PCUT_ASSERT_INT_EQUALS(0, u6->job->blocking_jobs);
+	PCUT_ASSERT_INT_EQUALS(0, u0->job->blocking_jobs);
+}
 
 PCUT_EXPORT(job_closure);
Index: uspace/srv/sysman/test/mock_unit.h
===================================================================
--- uspace/srv/sysman/test/mock_unit.h	(revision 015b147d9719aa8732f3b739eb43489e1d44f708)
+++ uspace/srv/sysman/test/mock_unit.h	(revision be07995661547b856a461a29a94ec0fbbb5a8fb0)
@@ -36,5 +36,5 @@
 #include "../unit.h"
 
-#define MAX_UNITS 5
+#define MAX_UNITS 7
 #define MAX_TYPES 4
 
