void krg_task_fill(struct task_struct *task, unsigned long clone_flags) { struct task_kddm_object *obj = task->task_obj; BUG_ON((task_tgid_knr(task) & GLOBAL_PID_MASK) != (task_pid_knr(task) & GLOBAL_PID_MASK)); #ifdef CONFIG_KRG_EPM if (krg_current) return; #endif if (!obj) return; obj->node = kerrighed_node_id; #ifdef CONFIG_KRG_EPM if (task->real_parent == baby_sitter) { BUG_ON(!current->task_obj); if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { struct task_kddm_object *cur_obj = current->task_obj; obj->real_parent = cur_obj->real_parent; obj->real_parent_tgid = cur_obj->real_parent_tgid; } else { obj->real_parent = task_pid_knr(current); obj->real_parent_tgid = task_tgid_knr(current); } } else #endif { obj->real_parent = task_pid_knr(task->real_parent); obj->real_parent_tgid = task_tgid_knr(task->real_parent); } /* Keep parent same as real_parent until ptrace is better supported */ obj->parent = obj->real_parent; #ifdef CONFIG_KRG_EPM /* Distributed threads are not supported yet. */ BUG_ON(task->group_leader == baby_sitter); #endif obj->group_leader = task_tgid_knr(task); }
int cr_link_to_file(struct epm_action *action, ghost_t *ghost, struct task_struct *task, struct file **returned_file) { int r; long key; enum shared_obj_type type; struct cr_file_link *file_link; BUG_ON(action->type != EPM_CHECKPOINT); /* files are linked while loading files_struct or mm_struct */ BUG_ON(action->restart.shared != CR_LOAD_NOW); r = ghost_read(ghost, &type, sizeof(enum shared_obj_type)); if (r) goto error; if (type != LOCAL_FILE && type != DVFS_FILE) goto err_bad_data; r = ghost_read(ghost, &key, sizeof(long)); if (r) goto error; /* look in the table to find the new allocated data * imported in import_shared_objects */ file_link = get_imported_shared_object(action->restart.app, type, key); if (file_link->desc_type == CR_FILE_NONE) { *returned_file = NULL; r = 0; } else r = __cr_link_to_file(action, ghost, task, file_link, returned_file); error: if (r) ckpt_err(NULL, r, "Fail to relink process %d of application %ld" " to file %d:%lu", task_pid_knr(task), action->restart.app->app_id, type, key); return r; err_bad_data: r = -E_CR_BADDATA; goto error; }
int krg_unset_pid_location(struct task_struct *task) { struct task_kddm_object *p; BUG_ON(!(task_pid_knr(task) & GLOBAL_PID_MASK)); p = __krg_task_writelock(task); BUG_ON(p == NULL); p->node = KERRIGHED_NODE_ID_NONE; __krg_task_unlock(task); return 0; }
static int cr_export_now_file(struct epm_action *action, ghost_t *ghost, struct task_struct *task, union export_args *args) { int r, supported; supported = can_checkpoint_file(args->file_args.file); r = ghost_write(ghost, &supported, sizeof(supported)); if (r) goto error; if (supported) r = regular_file_export(action, ghost, task, args->file_args.index, args->file_args.file); error: if (r) { char *buffer, *filename; filename = alloc_filename(args->file_args.file, &buffer); if (!IS_ERR(filename)) { ckpt_err(action, r, "Fail to save information needed to reopen " "file %s as fd %d of process %d (%s)", filename, args->file_args.index, task_pid_knr(task), task->comm); free_filename(buffer); } else { ckpt_err(action, r, "Fail to save information needed to reopen " "fd %d of process %d (%s)", args->file_args.index, task_pid_knr(task), task->comm); } } return r; }
/* Checkpoint signal handler */ static void krg_task_checkpoint(int sig, struct siginfo *info, struct pt_regs *regs) { struct epm_action action; task_state_t *current_state; int r = 0; action.type = EPM_CHECKPOINT; action.checkpoint.appid = current->application->app_id; /* * process must not be frozen while its father * waiting in vfork */ if (current->vfork_done) { mutex_lock(¤t->application->mutex); r = -EAGAIN; app_error("freeze", r, current->application->app_id, "Process %d (%s) has been created by vfork() and has " "not yet called exec(). Thus, its parent process is " "blocked.", task_pid_knr(current), current->comm); __set_task_result(current, r); mutex_unlock(¤t->application->mutex); goto out; } /* freeze */ current_state = set_result_wait(PCUS_OPERATION_OK); if (IS_ERR(current_state)) goto out; /* * checkpoint may be requested several times once * application is frozen. */ while (current_state->checkpoint.ghost) { action.checkpoint.shared = CR_SAVE_LATER; r = checkpoint_task(&action, current, regs); /* PCUS_OPERATION_OK == 0 */ current_state = set_result_wait(r); } out: return; }
void __krg_task_unlock(struct task_struct *task) { krg_task_unlock(task_pid_knr(task)); }
struct task_kddm_object *__krg_task_writelock_nested(struct task_struct *task) { return task_writelock(task_pid_knr(task), 1); }
struct task_kddm_object *__krg_task_readlock(struct task_struct *task) { return krg_task_readlock(task_pid_knr(task)); }
void __krg_task_free(struct task_struct *task) { _kddm_remove_object(task_kddm_set, task_pid_knr(task)); }