summaryrefslogtreecommitdiffstats
path: root/libcg.h
blob: 88f5a45a202423104998e109dbb7be95202ddeb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * Copyright IBM Corporation. 2007
 *
 * Author:	Balbir Singh <balbir@linux.vnet.ibm.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2.1 of the GNU Lesser General Public License
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#ifndef _LIBCG_H
#define _LIBCG_H

#include <features.h>

__BEGIN_DECLS

#include <grp.h>
#include <linux/types.h>
#include <stdio.h>
#include <sys/stat.h>

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifndef __USE_GNU
#define __USE_GNU
#endif

/* Maximum number of mount points/controllers */
#define MAX_MNT_ELEMENTS	8
/* Estimated number of groups created */
#define MAX_GROUP_ELEMENTS	128

#ifdef DEBUG
#define dbg(x...) printf(x)
#else
#define dbg(x...) do {} while(0)
#endif

/*
 * NOTE: Wide characters are not supported at the moment. Wide character support
 * would require us to use a scanner/parser that can parse beyond ASCII
 */

/*
 * These data structures are heavily controller dependent, which means
 * any changes (additions/removal) of configuration items would have to
 *  be reflected in this library. We might implement a plugin
 *  infrastructure, so that we can deal with such changes with ease.
 */

struct cpu_controller {
	/*TODO: Add the cpu.usage file here, also need to automate this.*/
	char *shares;	/* Having strings helps us write them to files */
	/*
	 * XX: No it does not make a difference. It requires a fprintf anyway
	 * so it needs the qualifier.
	 */
};

struct cg_group {
	char *name;
	uid_t tasks_uid;
	gid_t tasks_gid;
	uid_t admin_uid;
	gid_t admin_gid;
	struct cpu_controller cpu_config;
};

/*
 * A singly linked list suffices since we don't expect too many mount points
 */
struct mount_table {
	char *options;		/* Name(s) of the controller */
	char *mount_point;	/* The place where the controller is mounted */
	struct mount_table *next;
};

/*
 * Maintain a list of all group names. These will be used during cleanup
 */
struct list_of_names {
	char *name;
	struct list_of_names *next;
};

enum cg_msg_type {
	CG_MSG_LOAD_FILE,
	CG_MSG_UNLOAD_FILE,
	CG_MSG_ERR,
	CG_MSG_DONE,
};

enum cg_errors {
	ECGROUPNOTCOMPILED=50000,
	ECGROUPNOTMOUNTED,
	ECGROUPNOTEXIST,
	ECGROUPNOTCREATED,
	ECGROUPSUBSYSNOTMOUNTED,
	ECGROUPNOTOWNER,
	ECGROUPMULTIMOUNTED,/* Controllers bound to different mount points */
	ECGROUPNOTALLOWED,  /* This is the stock error. Default error. */
};

#define CG_MAX_MSG_SIZE		256
#define CG_SERVER_MSG_PATH	"/tmp/control_group"
#define CG_BACKLOG		5

/* Message's exchanged between server and client */
struct cg_msg {
	enum cg_msg_type type;
	char buf[CG_MAX_MSG_SIZE];
};

/* Function Prototypes start here */
int cg_init_group_and_mount_info(void);
int cg_insert_into_mount_table(const char *name, const char *mount_point);
void cg_cleanup_mount_table(void);
int cg_group_admin_perm(char *perm_type, char *value);
int cg_group_task_perm(char *perm_type, char *value);
int cg_parse_controller_options(char *controller, char *name_value);
int cg_insert_group(const char *group_name);
int chown_recursive(const char* path, uid_t owner, gid_t group);
int cg_make_directory(struct cg_group *cg_group, const char *group_path);
char *cg_build_group_path(struct cg_group *cg_group,
					struct mount_table *mount_info);
int cg_mount_controllers(void);
int cg_unmount_controllers(void);
int cg_load_config(const char *pathname);
void cg_unload_current_config(void);

#define CG_NV_MAX 100
#define CG_CONTROLLER_MAX 100
/* Functions and structures that can be used by the application*/
struct control_value {
	char name[FILENAME_MAX];
	char *value;
};

struct controller {
	char *name;
	struct control_value *values[CG_NV_MAX];
};

struct cgroup {
	char *name;
	struct controller *controller[CG_CONTROLLER_MAX];
	uid_t tasks_uid;
	gid_t tasks_gid;
	uid_t control_uid;
	gid_t control_gid;
};

int cg_init(void);
int cg_attach_task(struct cgroup *cgroup);
int cg_modify_cgroup(struct cgroup *cgroup);
int cg_create_cgroup(struct cgroup *cgroup, int ignore_ownership);
int cg_delete_cgroup(struct cgroup *cgroup, int ignore_migration);

__END_DECLS

#endif /* _LIBCG_H  */