asmlinkage int sys_dpm(int func, struct dpm_param *params) { struct dpm_param p; if (current->uid != 0) /* root-only access for now */ return -EACCES; if (params) { if (0 != copy_from_user(&p, params, sizeof (struct dpm_param))) { return -EFAULT; } } switch (func) { case DPM_INIT: return dpm_init(); case DPM_TERMINATE: return dpm_terminate(); case DPM_DISABLE: return dpm_disable(); case DPM_ENABLE: return dpm_enable(); case DPM_CREATE_OPT: sys_dpm_param_check(params); return u_dpm_create_opt(p.name, p.pp); case DPM_CREATE_CLASS: sys_dpm_param_check(params); return u_dpm_create_class(p.name, p.m_names, p.m_count); case DPM_CREATE_POLICY: sys_dpm_param_check(params); return u_dpm_create_policy(p.name, p.m_names); case DPM_DESTROY_POLICY: sys_dpm_param_check(params); return u_dpm_destroy_policy(p.name); case DPM_SET_POLICY: sys_dpm_param_check(params); return u_dpm_set_policy(p.name); case DPM_GET_POLICY: sys_dpm_param_check(params); return u_dpm_get_policy(params->name); case DPM_GET_ALL_POLICIES: sys_dpm_param_check(params); return u_dpm_get_all_policies(p.name, p.m_names); case DPM_GET_CLASSES: sys_dpm_param_check(params); return u_dpm_get_classes(p.name, p.m_names); case DPM_SET_TASK_STATE: sys_dpm_param_check(params); return u_dpm_set_task_state(p.pid, p.task_state); case DPM_GET_TASK_STATE: sys_dpm_param_check(params); return u_dpm_get_task_state(p.pid, ¶ms->task_state); #ifdef CONFIG_DPM_STATS /* query statistics */ case DPM_GET_POLICY_STATS: sys_dpm_param_check(params); return u_dpm_get_policy_stats(p.name, params); case DPM_GET_CLASS_STATS: sys_dpm_param_check(params); return u_dpm_get_class_stats(p.name, params); case DPM_GET_OS_STATS: sys_dpm_param_check(params); return u_dpm_get_os_stats(params); #ifdef CONFIG_DPM_OPT_STATS case DPM_GET_OPT_STATS: sys_dpm_param_check(params); return u_dpm_get_opt_stats(p.name, params); #endif /* CONFIG_DPM_OPT_STATS */ #endif /* CONFIG_DPM_STATS */ /* for debug */ case DPM_DISPLAY_POLICY: sys_dpm_param_check(params); u_dpm_display_policy(p.name); return 0; default: return -EBADRQC; } }
static int write_proc_dpm_cmd (struct file *file, const char *buffer, unsigned long count, void *data) { char *buf, *tok, **tokptrs; char *whitespace = " \t\r\n"; int ret = 0, ntoks; if (current->uid != 0) return -EACCES; if (count == 0) return 0; if (!(buf = kmalloc(count + 1, GFP_KERNEL))) return -ENOMEM; if (copy_from_user(buf, buffer, count)) { ret = -EFAULT; goto out0; } buf[count] = '\0'; if (!(tokptrs = (char **)__get_free_page(GFP_KERNEL))) { ret = -ENOMEM; goto out1; } ret = -EINVAL; ntoks = 0; do { buf = buf + strspn(buf, whitespace); tok = strsep(&buf, whitespace); if (*tok == '\0') { if (ntoks == 0) { ret = 0; goto out1; } else break; } if (ntoks == (PAGE_SIZE / sizeof(char **))) goto out1; tokptrs[ntoks++] = tok; } while(buf); if (ntoks == 1) { if (strcmp(tokptrs[0], "init") == 0) { ret = dpm_init(); } else if (strcmp(tokptrs[0], "enable") == 0) { ret = dpm_enable(); } else if (strcmp(tokptrs[0], "disable") == 0) { ret = dpm_disable(); } else if (strcmp(tokptrs[0], "terminate") == 0) { ret = dpm_terminate(); } } else if (ntoks == 2) { if (strcmp(tokptrs[0], "set_policy") == 0) ret = dpm_set_policy(tokptrs[1]); else if (strcmp(tokptrs[0], "set_state") == 0) ret = dpm_set_op_state(tokptrs[1]); } else { if (strcmp(tokptrs[0], "set_task_state") == 0) { if (ntoks != 3) pwarn("set_task_state", ntoks, "", 3); else ret = dpm_set_task_state(simple_strtol(tokptrs[1], NULL, 0), simple_strtol(tokptrs[2], NULL, 0)); } else if (strcmp(tokptrs[0], "create_opt") == 0) { if (ntoks != DPM_PP_NBR + 2) pwarn("create_opt", ntoks, "", DPM_PP_NBR + 2); else { dpm_md_pp_t pp[DPM_PP_NBR]; int i; for (i = 0; i < DPM_PP_NBR; i++) pp[i] = simple_strtol(tokptrs[i + 2], NULL, 0); ret = dpm_create_opt(tokptrs[1], pp); } } else if (strcmp(tokptrs[0], "create_class") == 0) { if (ntoks < 3) pwarn("create_class", ntoks, ">= ", 3); else ret = dpm_create_class(tokptrs[1], &tokptrs[2], ntoks - 2); } else if (strcmp(tokptrs[0], "create_policy") == 0) { if (ntoks != (DPM_STATES + 2)) pwarn("create_policy", ntoks, "", DPM_STATES + 2); else ret = dpm_create_policy(tokptrs[1], &tokptrs[2]); } } out1: free_page((unsigned long)tokptrs); out0: kfree(buf); if (ret == 0) return count; else return ret; }