summaryrefslogtreecommitdiff
path: root/examples/vm_power_manager/channel_manager.h
blob: d948b304c416a003a34704250284b8eb4f721a2c (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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(c) 2010-2014 Intel Corporation
 */

#ifndef CHANNEL_MANAGER_H_
#define CHANNEL_MANAGER_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <linux/limits.h>
#include <sys/un.h>
#include <rte_atomic.h>

/* Maximum number of CPUs */
#define CHANNEL_CMDS_MAX_CPUS        64
#if CHANNEL_CMDS_MAX_CPUS > 64
#error Maximum number of cores is 64, overflow is guaranteed to \
    cause problems with VM Power Management
#endif

/* Maximum name length including '\0' terminator */
#define CHANNEL_MGR_MAX_NAME_LEN    64

/* Maximum number of channels to each Virtual Machine */
#define CHANNEL_MGR_MAX_CHANNELS    64

/* Hypervisor Path for libvirt(qemu/KVM) */
#define CHANNEL_MGR_DEFAULT_HV_PATH "qemu:///system"

/* File socket directory */
#define CHANNEL_MGR_SOCKET_PATH     "/tmp/powermonitor/"

#ifndef UNIX_PATH_MAX
struct sockaddr_un _sockaddr_un;
#define UNIX_PATH_MAX sizeof(_sockaddr_un.sun_path)
#endif

#define MAX_CLIENTS 64
#define MAX_VCPUS 20


struct libvirt_vm_info {
	const char *vm_name;
	unsigned int pcpus[MAX_VCPUS];
	uint8_t num_cpus;
};

struct libvirt_vm_info lvm_info[MAX_CLIENTS];
/* Communication Channel Status */
enum channel_status { CHANNEL_MGR_CHANNEL_DISCONNECTED = 0,
	CHANNEL_MGR_CHANNEL_CONNECTED,
	CHANNEL_MGR_CHANNEL_DISABLED,
	CHANNEL_MGR_CHANNEL_PROCESSING};

/* Communication Channel Type */
enum channel_type {
	CHANNEL_TYPE_BINARY = 0,
	CHANNEL_TYPE_INI,
	CHANNEL_TYPE_JSON
};

/* VM libvirt(qemu/KVM) connection status */
enum vm_status { CHANNEL_MGR_VM_INACTIVE = 0, CHANNEL_MGR_VM_ACTIVE};

/*
 *  Represents a single and exclusive VM channel that exists between a guest and
 *  the host.
 */
struct channel_info {
	char channel_path[UNIX_PATH_MAX]; /**< Path to host socket */
	volatile uint32_t status;    /**< Connection status(enum channel_status) */
	int fd;                      /**< AF_UNIX socket fd */
	unsigned channel_num;        /**< CHANNEL_MGR_SOCKET_PATH/<vm_name>.channel_num */
	enum channel_type type;      /**< Binary, ini, json, etc. */
	void *priv_info;             /**< Pointer to private info, do not modify */
};

/* Represents a single VM instance used to return internal information about
 * a VM */
struct vm_info {
	char name[CHANNEL_MGR_MAX_NAME_LEN];          /**< VM name */
	enum vm_status status;                        /**< libvirt status */
	uint64_t pcpu_mask[CHANNEL_CMDS_MAX_CPUS];    /**< pCPU mask for each vCPU */
	unsigned num_vcpus;                           /**< number of vCPUS */
	struct channel_info channels[CHANNEL_MGR_MAX_CHANNELS]; /**< Array of channel_info */
	unsigned num_channels;                        /**< Number of channels */
};

/**
 * Initialize the Channel Manager resources and connect to the Hypervisor
 * specified in path.
 * This must be successfully called first before calling any other functions.
 * It must only be call once;
 *
 * @param path
 *  Must be a local path, e.g. qemu:///system.
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int channel_manager_init(const char *path);

/**
 * Free resources associated with the Channel Manager.
 *
 * @param path
 *  Must be a local path, e.g. qemu:///system.
 *
 * @return
 *  None
 */
void channel_manager_exit(void);

/**
 * Get the Physical CPU mask for VM lcore channel(vcpu), result is assigned to
 * core_mask.
 * It is not thread-safe.
 *
 * @param chan_info
 *  Pointer to struct channel_info
 *
 * @param vcpu
 *  The virtual CPU to query.
 *
 *
 * @return
 *  - 0 on error.
 *  - >0 on success.
 */
uint64_t get_pcpus_mask(struct channel_info *chan_info, unsigned vcpu);

/**
 * Set the Physical CPU mask for the specified vCPU.
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to lookup
 *
 * @param vcpu
 *  The virtual CPU to set.
 *
 * @param core_mask
 *  The core mask of the physical CPU(s) to bind the vCPU
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int set_pcpus_mask(char *vm_name, unsigned vcpu, uint64_t core_mask);

/**
 * Set the Physical CPU for the specified vCPU.
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to lookup
 *
 * @param vcpu
 *  The virtual CPU to set.
 *
 * @param core_num
 *  The core number of the physical CPU(s) to bind the vCPU
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int set_pcpu(char *vm_name, unsigned vcpu, unsigned core_num);
/**
 * Add a VM as specified by name to the Channel Manager. The name must
 * correspond to a valid libvirt domain name.
 * This is required prior to adding channels.
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to lookup.
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int add_vm(const char *name);

/**
 * Remove a previously added Virtual Machine from the Channel Manager
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to lookup.
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int remove_vm(const char *name);

/**
 * Add all available channels to the VM as specified by name.
 * Channels in the form of paths
 * (CHANNEL_MGR_SOCKET_PATH/<vm_name>.<channel_number>) will only be parsed.
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to lookup.
 *
 * @return
 *  - N the number of channels added for the VM
 */
int add_all_channels(const char *vm_name);

/**
 * Add the channel numbers in channel_list to the domain specified by name.
 * Channels in the form of paths
 * (CHANNEL_MGR_SOCKET_PATH/<vm_name>.<channel_number>) will only be parsed.
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to add channels.
 *
 * @param channel_list
 *  Pointer to list of unsigned integers, representing the channel number to add
 *  It must be allocated outside of this function.
 *
 * @param num_channels
 *  The amount of channel numbers in channel_list
 *
 * @return
 *  - N the number of channels added for the VM
 *  - 0 for error
 */
int add_channels(const char *vm_name, unsigned *channel_list,
		unsigned num_channels);

/**
 * Set up a fifo by which host applications can send command an policies
 * through a fifo to the vm_power_manager
 *
 * @return
 *  - 0 for success
 */
int add_host_channel(void);

/**
 * Remove a channel definition from the channel manager. This must only be
 * called from the channel monitor thread.
 *
 * @param chan_info
 *  Pointer to a valid struct channel_info.
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int remove_channel(struct channel_info **chan_info_dptr);

/**
 * For all channels associated with a Virtual Machine name, update the
 * connection status. Valid states are CHANNEL_MGR_CHANNEL_CONNECTED or
 * CHANNEL_MGR_CHANNEL_DISABLED only.
 *
 *
 * @param name
 *  Virtual Machine name to modify all channels.
 *
 * @param status
 *  The status to set each channel
 *
 * @param num_channels
 *  The amount of channel numbers in channel_list
 *
 * @return
 *  - N the number of channels added for the VM
 *  - 0 for error
 */
int set_channel_status_all(const char *name, enum channel_status status);

/**
 * For all channels in channel_list associated with a Virtual Machine name
 * update the connection status of each.
 * Valid states are CHANNEL_MGR_CHANNEL_CONNECTED or
 * CHANNEL_MGR_CHANNEL_DISABLED only.
 * It is not thread-safe.
 *
 * @param name
 *  Virtual Machine name to add channels.
 *
 * @param channel_list
 *  Pointer to list of unsigned integers, representing the channel numbers to
 *  modify.
 *  It must be allocated outside of this function.
 *
 * @param num_channels
 *  The amount of channel numbers in channel_list
 *
 * @return
 *  - N the number of channels modified for the VM
 *  - 0 for error
 */
int set_channel_status(const char *vm_name, unsigned *channel_list,
		unsigned len_channel_list, enum channel_status status);

/**
 * Populates a pointer to struct vm_info associated with vm_name.
 *
 * @param vm_name
 *  The name of the virtual machine to lookup.
 *
 *  @param vm_info
 *   Pointer to a struct vm_info, this must be allocated prior to calling this
 *   function.
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int get_info_vm(const char *vm_name, struct vm_info *info);

/**
 * Populates a table with all domains running and their physical cpu.
 * All information is gathered through libvirt api.
 *
 * @param num_vm
 *  modified to store number of active VMs
 *
 * @param num_vcpu
    modified to store number of vcpus active
 *
 * @return
 *   void
 */
void get_all_vm(int *num_vm, int *num_vcpu);
#ifdef __cplusplus
}
#endif

#endif /* CHANNEL_MANAGER_H_ */