struct process_context {
pid_t tgid;
+ pid_t ppid;
+ pid_t pgid;
char comm[TS_COMM_LEN];
struct taskstats prev;
struct taskstats curr;
return 0;
}
-static int process_get_comm(const struct resource *res,
+static int process_get_context_data(const struct resource *res,
const struct resource_attribute *attr,
void *data)
{
struct process_context *ctx;
- char *buf = (char *)data;
if (!res || !res->priv || !attr || !data)
return -EINVAL;
return -EINVAL;
}
- strncpy(buf, ctx->comm, TS_COMM_LEN);
+ switch (attr->id) {
+ case PROCESS_ATTR_COMM:
+ strncpy((char *)data, ctx->comm, TS_COMM_LEN);
+ break;
+ case PROCESS_ATTR_PGID:
+ *((int *)data) = ctx->pgid;
+ break;
+ case PROCESS_ATTR_PPID:
+ *((int *)data) = ctx->ppid;
+ break;
+ }
return 0;
}
.id = PROCESS_ATTR_COMM,
.type = DATA_TYPE_STRING,
.ops = {
- .get = process_get_comm,
+ .get = process_get_context_data,
+ },
+ }, {
+ .name = "PROCESS_ATTR_PGID",
+ .id = PROCESS_ATTR_PGID,
+ .type = DATA_TYPE_INT,
+ .ops = {
+ .get = process_get_context_data,
+ },
+ }, {
+ .name = "PROCESS_ATTR_PPID",
+ .id = PROCESS_ATTR_PPID,
+ .type = DATA_TYPE_INT,
+ .ops = {
+ .get = process_get_context_data,
},
},
};
const struct resource_control *ctrl,
const void *data)
{
- struct taskstats stats;
+ char buf[BUFF_MAX];
+ char *stat_fields[PROCESS_STAT_FIELD_MAX];
struct process_context *ctx;
u_int64_t total_memory;
int ret;
/* update initial status */
ret = update_taskstats(ctx);
if (ret < 0)
- return -EINVAL;
+ return ret;
- ret = query_taskstats(&stats, TASKSTATS_CMD_ATTR_PID, ctx->tgid);
+ ret = kernel_get_process_stat_fields(ctx->tgid, buf, BUFF_MAX, stat_fields);
if (ret < 0)
- return -EINVAL;
+ return ret;
+
+ /* save comm with removing parentheses */
+ strncpy(ctx->comm, stat_fields[PROCESS_STAT_FIELD_COMM] + 1,
+ strlen(stat_fields[PROCESS_STAT_FIELD_COMM]) - 2 /* '(', ')' */);
- memcpy(ctx->comm, stats.ac_comm, TS_COMM_LEN);
+ ctx->pgid = atoi(stat_fields[PROCESS_STAT_FIELD_PGID]);
+ ctx->ppid = atoi(stat_fields[PROCESS_STAT_FIELD_PPID]);
return 0;
}