*/
int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
{
+ LIST_HEAD(preloaded_csets);
+ struct cgrp_cset_link *link;
struct css_task_iter it;
struct task_struct *task;
- int ret = 0;
+ int ret;
+
+ mutex_lock(&cgroup_mutex);
+
+ /* all tasks in @from are being moved, all csets are source */
+ down_read(&css_set_rwsem);
+ list_for_each_entry(link, &from->cset_links, cset_link)
+ cgroup_migrate_add_src(link->cset, to, &preloaded_csets);
+ up_read(&css_set_rwsem);
+ ret = cgroup_migrate_prepare_dst(to, &preloaded_csets);
+ if (ret)
+ goto out_err;
+
+ /*
+ * Migrate tasks one-by-one until @form is empty. This fails iff
+ * ->can_attach() fails.
+ */
do {
css_task_iter_start(&from->dummy_css, &it);
task = css_task_iter_next(&it);
css_task_iter_end(&it);
if (task) {
- mutex_lock(&cgroup_mutex);
- ret = cgroup_attach_task(to, task, false);
- mutex_unlock(&cgroup_mutex);
+ ret = cgroup_migrate(to, task, false);
put_task_struct(task);
}
} while (task && !ret);
-
+out_err:
+ cgroup_migrate_finish(&preloaded_csets);
+ mutex_unlock(&cgroup_mutex);
return ret;
}