Index: uspace/lib/c/include/ipc/sysman.h
===================================================================
--- uspace/lib/c/include/ipc/sysman.h	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/lib/c/include/ipc/sysman.h	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -69,5 +69,4 @@
 
 typedef enum {
-	STATE_EMBRYO = 0, // embryo is orthogonal to states (again convergence to systemd...)
 	STATE_STARTING,
 	STATE_STARTED,
Index: uspace/srv/sysman/repo.c
===================================================================
--- uspace/srv/sysman/repo.c	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/repo.c	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -74,5 +74,5 @@
 	.equal           = &units_by_handle_ht_equal,
 	.key_equal       = &units_by_handle_ht_key_equal,
-	.remove_callback = NULL // TODO realy unneeded?
+	.remove_callback = NULL
 };
 
@@ -108,8 +108,18 @@
 	.equal           = &units_by_name_ht_equal,
 	.key_equal       = &units_by_name_ht_key_equal,
-	.remove_callback = NULL // TODO realy unneeded?
+	.remove_callback = NULL
 };
 
 /* Repository functions */
+
+static void repo_remove_unit_internal(unit_t *u)
+{
+	hash_table_remove_item(&units_by_name, &u->units_by_name);
+	hash_table_remove_item(&units_by_handle, &u->units_by_handle);
+	list_remove(&u->units);
+
+	// TODO decrease refcount of unit
+	// unit may be referenced e.g. from running job, thus we cannot simply destroy it
+}
 
 void repo_init(void)
@@ -122,5 +132,5 @@
 {
 	assert(unit);
-	assert(unit->state == STATE_EMBRYO);
+	assert(unit->repo_state == REPO_EMBRYO);
 	assert(unit->handle == 0);
 	assert(unit->name != NULL);
@@ -139,4 +149,10 @@
 }
 
+int repo_remove_unit(unit_t *unit)
+{
+	unit->repo_state = REPO_ZOMBIE;
+	return EOK; /* We could check that unit is present in repo etc... */
+}
+
 void repo_begin_update(void) {
 	sysman_log(LVL_DEBUG2, "%s", __func__);
@@ -146,6 +162,11 @@
 {
 	unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
-	if (unit->state == STATE_EMBRYO) {
-		unit->state = STATE_STOPPED;
+	if (unit->repo_state == REPO_ZOMBIE) {
+		repo_remove_unit_internal(unit);
+		return true;
+	}
+
+	if (unit->repo_state == REPO_EMBRYO) {
+		unit->repo_state = REPO_LIVING;
 	}
 
@@ -162,6 +183,8 @@
 
 	/*
-	 * Apply commit to all units_by_name, each commited unit commits its outgoing
-	 * deps, thus eventually commiting all embryo deps as well.
+	 * Apply commit to all units_by_name, each commited unit commits its
+	 * outgoing deps, thus eventually commiting all embryo deps as well.
+	 *
+	 * TODO why not iterate over units list?
 	 */
 	hash_table_apply(&units_by_name, &repo_commit_unit, NULL);
@@ -180,8 +203,8 @@
 	}
 
-	if (unit->state == STATE_EMBRYO) {
-		hash_table_remove_item(&units_by_name, ht_link);
-		list_remove(&unit->units);
-		unit_destroy(&unit);
+	if (unit->repo_state == REPO_EMBRYO) {
+		repo_remove_unit_internal(unit);
+	} else if (unit->repo_state == REPO_ZOMBIE) {
+		unit->repo_state = REPO_LIVING;
 	}
 
Index: uspace/srv/sysman/repo.h
===================================================================
--- uspace/srv/sysman/repo.h	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/repo.h	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -32,6 +32,9 @@
 #include <adt/list.h>
 #include <ipc/sysman.h>
+#include <stdio.h>
 
 #include "unit.h"
+
+#define ANONYMOUS_SERVICE_MASK "service_%" PRIu64
 
 extern list_t units;
@@ -40,4 +43,5 @@
 
 extern int repo_add_unit(unit_t *);
+extern int repo_remove_unit(unit_t *);
 
 extern void repo_begin_update(void);
Index: uspace/srv/sysman/sm_task.c
===================================================================
--- uspace/srv/sysman/sm_task.c	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/sm_task.c	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -28,6 +28,8 @@
 
 #include <adt/list.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <task.h>
+#include <sysman/unit.h>
 
 #include "repo.h"
@@ -35,4 +37,5 @@
 #include "sysman.h"
 #include "sm_task.h"
+
 
 /** Structure for boxing task event */
@@ -85,4 +88,60 @@
 }
 
+static unit_svc_t *sm_task_create_service(task_id_t tid)
+{
+	unit_t *u_svc = unit_create(UNIT_SERVICE);
+	bool in_repo_update = false;
+	int rc = EOK;
+
+	if (u_svc == NULL) {
+		goto fail;
+	}
+
+	rc = asprintf(&u_svc->name, ANONYMOUS_SERVICE_MASK "%c%s", tid,
+	    UNIT_NAME_SEPARATOR, UNIT_SVC_TYPE_NAME);
+	if (rc < 0) {
+		goto fail;
+	}
+
+	CAST_SVC(u_svc)->main_task_id = tid;
+	CAST_SVC(u_svc)->anonymous = true;
+	/* exec_start is left undefined, maybe could be hinted by kernel's task
+	 * name */
+
+	repo_begin_update();
+	in_repo_update = true;
+
+	rc = repo_add_unit(u_svc);
+	if (rc != EOK) {
+		goto fail;
+	}
+
+	repo_commit();
+
+	return CAST_SVC(u_svc);
+	
+fail:
+	if (in_repo_update) {
+		repo_rollback();
+	}
+
+	unit_destroy(&u_svc);
+	return NULL;
+}
+
+static void sm_task_delete_service(unit_svc_t *u_svc)
+{
+	repo_begin_update();
+	int rc = repo_remove_unit(&u_svc->unit);
+	if (rc != EOK) {
+		sysman_log(LVL_WARN, "Can't remove unit %s (%i).",
+		    unit_name(&u_svc->unit), rc);
+		repo_rollback();
+		return;
+	}
+
+	repo_commit();
+}
+
 static void sysman_event_task_event(void *data)
 {
@@ -92,6 +151,24 @@
 	    __func__, tev->task_id, tev->flags);
 	unit_svc_t *u_svc = sm_task_find_service(tev->task_id);
+
 	if (u_svc == NULL) {
-		goto finish;
+		if (tev->flags & TASK_WAIT_EXIT) {
+			/* Non-service task exited, ignore. */
+			goto finish;
+		}
+
+		u_svc = sm_task_create_service(tev->task_id);
+		if (u_svc == NULL) {
+			sysman_log(LVL_WARN,
+			    "Unable to create anonymous service for task %" PRIu64 ".",
+			    tev->task_id);
+			goto finish;
+		}
+
+		sysman_log(LVL_DEBUG, "Created anonymous service %s.",
+		    unit_name(&u_svc->unit));
+
+		/* Inject state so that further processing makes sense */
+		u_svc->unit.state = STATE_STARTING;
 	}
 
@@ -111,4 +188,5 @@
 			u->state = STATE_FAILED;
 		}
+
 	}
 	if (tev->flags & TASK_WAIT_RETVAL) {
@@ -119,4 +197,9 @@
 	unit_notify_state(u);
 
+	if ((tev->flags & TASK_WAIT_EXIT) && u_svc->anonymous) {
+		sysman_log(LVL_DEBUG, "Deleted anonymous service %s.",
+		    unit_name(&u_svc->unit));
+		sm_task_delete_service(u_svc);
+	}
 finish:
 	free(tev);
Index: uspace/srv/sysman/unit.c
===================================================================
--- uspace/srv/sysman/unit.c	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/unit.c	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -68,5 +68,6 @@
 	
 	unit->type = type;
-	unit->state = STATE_EMBRYO;
+	unit->state = STATE_STOPPED;
+	unit->repo_state = REPO_EMBRYO;
 
 	link_initialize(&unit->units);
Index: uspace/srv/sysman/unit.h
===================================================================
--- uspace/srv/sysman/unit.h	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/unit.h	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -48,4 +48,11 @@
 struct job;
 
+/* Represents presence of unit in repo during modifications */
+typedef enum {
+	REPO_EMBRYO,
+	REPO_LIVING,
+	REPO_ZOMBIE
+} repo_state_t;
+
 typedef struct {
 	/** Link to name-to-unit hash table */
@@ -80,4 +87,6 @@
 
 	unit_state_t state;
+
+	repo_state_t repo_state;
 
 	list_t edges_in;
Index: uspace/srv/sysman/units/unit_cfg.c
===================================================================
--- uspace/srv/sysman/units/unit_cfg.c	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/units/unit_cfg.c	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -177,5 +177,5 @@
 		}
 
-		assert(unit->state == STATE_EMBRYO);
+		assert(unit->repo_state == REPO_EMBRYO);
 		repo_add_unit(unit);
 	}
Index: uspace/srv/sysman/units/unit_svc.h
===================================================================
--- uspace/srv/sysman/units/unit_svc.h	(revision 5353f50407f7ae5a9535111c34a7c4eebb98f895)
+++ uspace/srv/sysman/units/unit_svc.h	(revision 8ae8262489f2d8e205fbf1b5dee2ee0a11d392e4)
@@ -41,4 +41,6 @@
 
 	task_id_t main_task_id;
+
+	bool anonymous;
 } unit_svc_t;
 
