1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifndef CHANNEL_MANAGER_H_ 35 #define CHANNEL_MANAGER_H_ 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #include <linux/limits.h> 42 #include <sys/un.h> 43 #include <rte_atomic.h> 44 45 /* Maximum number of CPUs */ 46 #define CHANNEL_CMDS_MAX_CPUS 64 47 #if CHANNEL_CMDS_MAX_CPUS > 64 48 #error Maximum number of cores is 64, overflow is guaranteed to \ 49 cause problems with VM Power Management 50 #endif 51 52 /* Maximum name length including '\0' terminator */ 53 #define CHANNEL_MGR_MAX_NAME_LEN 64 54 55 /* Maximum number of channels to each Virtual Machine */ 56 #define CHANNEL_MGR_MAX_CHANNELS 64 57 58 /* Hypervisor Path for libvirt(qemu/KVM) */ 59 #define CHANNEL_MGR_DEFAULT_HV_PATH "qemu:///system" 60 61 /* File socket directory */ 62 #define CHANNEL_MGR_SOCKET_PATH "/tmp/powermonitor/" 63 64 #ifndef UNIX_PATH_MAX 65 struct sockaddr_un _sockaddr_un; 66 #define UNIX_PATH_MAX sizeof(_sockaddr_un.sun_path) 67 #endif 68 69 /* Communication Channel Status */ 70 enum channel_status { CHANNEL_MGR_CHANNEL_DISCONNECTED = 0, 71 CHANNEL_MGR_CHANNEL_CONNECTED, 72 CHANNEL_MGR_CHANNEL_DISABLED, 73 CHANNEL_MGR_CHANNEL_PROCESSING}; 74 75 /* VM libvirt(qemu/KVM) connection status */ 76 enum vm_status { CHANNEL_MGR_VM_INACTIVE = 0, CHANNEL_MGR_VM_ACTIVE}; 77 78 /* 79 * Represents a single and exclusive VM channel that exists between a guest and 80 * the host. 81 */ 82 struct channel_info { 83 char channel_path[UNIX_PATH_MAX]; /**< Path to host socket */ 84 volatile uint32_t status; /**< Connection status(enum channel_status) */ 85 int fd; /**< AF_UNIX socket fd */ 86 unsigned channel_num; /**< CHANNEL_MGR_SOCKET_PATH/<vm_name>.channel_num */ 87 void *priv_info; /**< Pointer to private info, do not modify */ 88 }; 89 90 /* Represents a single VM instance used to return internal information about 91 * a VM */ 92 struct vm_info { 93 char name[CHANNEL_MGR_MAX_NAME_LEN]; /**< VM name */ 94 enum vm_status status; /**< libvirt status */ 95 uint64_t pcpu_mask[CHANNEL_CMDS_MAX_CPUS]; /**< pCPU mask for each vCPU */ 96 unsigned num_vcpus; /**< number of vCPUS */ 97 struct channel_info channels[CHANNEL_MGR_MAX_CHANNELS]; /**< Array of channel_info */ 98 unsigned num_channels; /**< Number of channels */ 99 }; 100 101 /** 102 * Initialize the Channel Manager resources and connect to the Hypervisor 103 * specified in path. 104 * This must be successfully called first before calling any other functions. 105 * It must only be call once; 106 * 107 * @param path 108 * Must be a local path, e.g. qemu:///system. 109 * 110 * @return 111 * - 0 on success. 112 * - Negative on error. 113 */ 114 int channel_manager_init(const char *path); 115 116 /** 117 * Free resources associated with the Channel Manager. 118 * 119 * @param path 120 * Must be a local path, e.g. qemu:///system. 121 * 122 * @return 123 * None 124 */ 125 void channel_manager_exit(void); 126 127 /** 128 * Get the Physical CPU mask for VM lcore channel(vcpu), result is assigned to 129 * core_mask. 130 * It is not thread-safe. 131 * 132 * @param chan_info 133 * Pointer to struct channel_info 134 * 135 * @param vcpu 136 * The virtual CPU to query. 137 * 138 * 139 * @return 140 * - 0 on error. 141 * - >0 on success. 142 */ 143 uint64_t get_pcpus_mask(struct channel_info *chan_info, unsigned vcpu); 144 145 /** 146 * Set the Physical CPU mask for the specified vCPU. 147 * It is not thread-safe. 148 * 149 * @param name 150 * Virtual Machine name to lookup 151 * 152 * @param vcpu 153 * The virtual CPU to set. 154 * 155 * @param core_mask 156 * The core mask of the physical CPU(s) to bind the vCPU 157 * 158 * @return 159 * - 0 on success. 160 * - Negative on error. 161 */ 162 int set_pcpus_mask(char *vm_name, unsigned vcpu, uint64_t core_mask); 163 164 /** 165 * Set the Physical CPU for the specified vCPU. 166 * It is not thread-safe. 167 * 168 * @param name 169 * Virtual Machine name to lookup 170 * 171 * @param vcpu 172 * The virtual CPU to set. 173 * 174 * @param core_num 175 * The core number of the physical CPU(s) to bind the vCPU 176 * 177 * @return 178 * - 0 on success. 179 * - Negative on error. 180 */ 181 int set_pcpu(char *vm_name, unsigned vcpu, unsigned core_num); 182 /** 183 * Add a VM as specified by name to the Channel Manager. The name must 184 * correspond to a valid libvirt domain name. 185 * This is required prior to adding channels. 186 * It is not thread-safe. 187 * 188 * @param name 189 * Virtual Machine name to lookup. 190 * 191 * @return 192 * - 0 on success. 193 * - Negative on error. 194 */ 195 int add_vm(const char *name); 196 197 /** 198 * Remove a previously added Virtual Machine from the Channel Manager 199 * It is not thread-safe. 200 * 201 * @param name 202 * Virtual Machine name to lookup. 203 * 204 * @return 205 * - 0 on success. 206 * - Negative on error. 207 */ 208 int remove_vm(const char *name); 209 210 /** 211 * Add all available channels to the VM as specified by name. 212 * Channels in the form of paths 213 * (CHANNEL_MGR_SOCKET_PATH/<vm_name>.<channel_number>) will only be parsed. 214 * It is not thread-safe. 215 * 216 * @param name 217 * Virtual Machine name to lookup. 218 * 219 * @return 220 * - N the number of channels added for the VM 221 */ 222 int add_all_channels(const char *vm_name); 223 224 /** 225 * Add the channel numbers in channel_list to the domain specified by name. 226 * Channels in the form of paths 227 * (CHANNEL_MGR_SOCKET_PATH/<vm_name>.<channel_number>) will only be parsed. 228 * It is not thread-safe. 229 * 230 * @param name 231 * Virtual Machine name to add channels. 232 * 233 * @param channel_list 234 * Pointer to list of unsigned integers, representing the channel number to add 235 * It must be allocated outside of this function. 236 * 237 * @param num_channels 238 * The amount of channel numbers in channel_list 239 * 240 * @return 241 * - N the number of channels added for the VM 242 * - 0 for error 243 */ 244 int add_channels(const char *vm_name, unsigned *channel_list, 245 unsigned num_channels); 246 247 /** 248 * Remove a channel definition from the channel manager. This must only be 249 * called from the channel monitor thread. 250 * 251 * @param chan_info 252 * Pointer to a valid struct channel_info. 253 * 254 * @return 255 * - 0 on success. 256 * - Negative on error. 257 */ 258 int remove_channel(struct channel_info **chan_info_dptr); 259 260 /** 261 * For all channels associated with a Virtual Machine name, update the 262 * connection status. Valid states are CHANNEL_MGR_CHANNEL_CONNECTED or 263 * CHANNEL_MGR_CHANNEL_DISABLED only. 264 * 265 * 266 * @param name 267 * Virtual Machine name to modify all channels. 268 * 269 * @param status 270 * The status to set each channel 271 * 272 * @param num_channels 273 * The amount of channel numbers in channel_list 274 * 275 * @return 276 * - N the number of channels added for the VM 277 * - 0 for error 278 */ 279 int set_channel_status_all(const char *name, enum channel_status status); 280 281 /** 282 * For all channels in channel_list associated with a Virtual Machine name 283 * update the connection status of each. 284 * Valid states are CHANNEL_MGR_CHANNEL_CONNECTED or 285 * CHANNEL_MGR_CHANNEL_DISABLED only. 286 * It is not thread-safe. 287 * 288 * @param name 289 * Virtual Machine name to add channels. 290 * 291 * @param channel_list 292 * Pointer to list of unsigned integers, representing the channel numbers to 293 * modify. 294 * It must be allocated outside of this function. 295 * 296 * @param num_channels 297 * The amount of channel numbers in channel_list 298 * 299 * @return 300 * - N the number of channels modified for the VM 301 * - 0 for error 302 */ 303 int set_channel_status(const char *vm_name, unsigned *channel_list, 304 unsigned len_channel_list, enum channel_status status); 305 306 /** 307 * Populates a pointer to struct vm_info associated with vm_name. 308 * 309 * @param vm_name 310 * The name of the virtual machine to lookup. 311 * 312 * @param vm_info 313 * Pointer to a struct vm_info, this must be allocated prior to calling this 314 * function. 315 * 316 * @return 317 * - 0 on success. 318 * - Negative on error. 319 */ 320 int get_info_vm(const char *vm_name, struct vm_info *info); 321 322 #ifdef __cplusplus 323 } 324 #endif 325 326 #endif /* CHANNEL_MANAGER_H_ */ 327