1 /* 2 * vircgroupbackend.h: methods for cgroups backend 3 * 4 * Copyright (C) 2018 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see 18 * <http://www.gnu.org/licenses/>. 19 */ 20 21 #pragma once 22 23 #include "internal.h" 24 25 #include "vircgroup.h" 26 27 #define CGROUP_MAX_VAL 512 28 29 typedef enum { 30 VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */ 31 VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy 32 * before creating subcgroups and 33 * attaching tasks 34 */ 35 VIR_CGROUP_THREAD = 1 << 1, /* cgroup v2 handles threads differently */ 36 VIR_CGROUP_SYSTEMD = 1 << 2, /* with systemd and cgroups v2 we cannot 37 * manually enable controllers that systemd 38 * doesn't know how to delegate */ 39 } virCgroupBackendFlags; 40 41 typedef enum { 42 /* Adds a whole process with all threads to specific cgroup except 43 * to systemd named controller. */ 44 VIR_CGROUP_TASK_PROCESS = 1 << 0, 45 46 /* Same as VIR_CGROUP_TASK_PROCESS but it also adds the task to systemd 47 * named controller. */ 48 VIR_CGROUP_TASK_SYSTEMD = 1 << 1, 49 50 /* Moves only specific thread into cgroup except to systemd 51 * named controller. */ 52 VIR_CGROUP_TASK_THREAD = 1 << 2, 53 } virCgroupBackendTaskFlags; 54 55 typedef enum { 56 VIR_CGROUP_BACKEND_TYPE_V2 = 0, 57 VIR_CGROUP_BACKEND_TYPE_V1, 58 VIR_CGROUP_BACKEND_TYPE_LAST, 59 } virCgroupBackendType; 60 61 VIR_ENUM_DECL(virCgroupBackend); 62 63 typedef bool 64 (*virCgroupAvailableCB)(void); 65 66 typedef bool 67 (*virCgroupValidateMachineGroupCB)(virCgroup *group, 68 const char *name, 69 const char *drivername, 70 const char *machinename); 71 72 typedef int 73 (*virCgroupCopyMountsCB)(virCgroup *group, 74 virCgroup *parent); 75 76 typedef int 77 (*virCgroupCopyPlacementCB)(virCgroup *group, 78 const char *path, 79 virCgroup *parent); 80 81 typedef int 82 (*virCgroupDetectMountsCB)(virCgroup *group, 83 const char *mntType, 84 const char *mntOpts, 85 const char *mntDir); 86 87 typedef int 88 (*virCgroupDetectPlacementCB)(virCgroup *group, 89 const char *path, 90 const char *controllers, 91 const char *selfpath); 92 93 typedef int 94 (*virCgroupSetPlacementCB)(virCgroup *group, 95 const char *path); 96 97 typedef int 98 (*virCgroupValidatePlacementCB)(virCgroup *group, 99 pid_t pid); 100 101 typedef char * 102 (*virCgroupStealPlacementCB)(virCgroup *group); 103 104 typedef int 105 (*virCgroupDetectControllersCB)(virCgroup *group, 106 int controllers, 107 virCgroup *parent, 108 int detected); 109 110 typedef bool 111 (*virCgroupHasControllerCB)(virCgroup *cgroup, 112 int controller); 113 114 typedef int 115 (*virCgroupGetAnyControllerCB)(virCgroup *group); 116 117 typedef int 118 (*virCgroupPathOfControllerCB)(virCgroup *group, 119 int controller, 120 const char *key, 121 char **path); 122 123 typedef bool 124 (*virCgroupExistsCB)(virCgroup *group); 125 126 typedef int 127 (*virCgroupMakeGroupCB)(virCgroup *parent, 128 virCgroup *group, 129 bool create, 130 pid_t pid, 131 unsigned int flags); 132 133 typedef int 134 (*virCgroupRemoveCB)(virCgroup *group); 135 136 typedef int 137 (*virCgroupAddTaskCB)(virCgroup *group, 138 pid_t pid, 139 unsigned int flags); 140 141 typedef int 142 (*virCgroupHasEmptyTasksCB)(virCgroup *cgroup, 143 int controller); 144 145 typedef int 146 (*virCgroupKillRecursiveCB)(virCgroup *group, 147 int signum, 148 GHashTable *pids); 149 150 typedef int 151 (*virCgroupBindMountCB)(virCgroup *group, 152 const char *oldroot, 153 const char *mountopts); 154 155 typedef int 156 (*virCgroupSetOwnerCB)(virCgroup *cgroup, 157 uid_t uid, 158 gid_t gid, 159 int controllers); 160 161 typedef int 162 (*virCgroupSetBlkioWeightCB)(virCgroup *group, 163 unsigned int weight); 164 165 typedef int 166 (*virCgroupGetBlkioWeightCB)(virCgroup *group, 167 unsigned int *weight); 168 169 typedef int 170 (*virCgroupGetBlkioIoServicedCB)(virCgroup *group, 171 long long *bytes_read, 172 long long *bytes_write, 173 long long *requests_read, 174 long long *requests_write); 175 176 typedef int 177 (*virCgroupGetBlkioIoDeviceServicedCB)(virCgroup *group, 178 const char *path, 179 long long *bytes_read, 180 long long *bytes_write, 181 long long *requests_read, 182 long long *requests_write); 183 184 typedef int 185 (*virCgroupSetBlkioDeviceWeightCB)(virCgroup *group, 186 const char *path, 187 unsigned int weight); 188 189 typedef int 190 (*virCgroupGetBlkioDeviceWeightCB)(virCgroup *group, 191 const char *path, 192 unsigned int *weight); 193 194 typedef int 195 (*virCgroupSetBlkioDeviceReadIopsCB)(virCgroup *group, 196 const char *path, 197 unsigned int riops); 198 199 typedef int 200 (*virCgroupGetBlkioDeviceReadIopsCB)(virCgroup *group, 201 const char *path, 202 unsigned int *riops); 203 204 typedef int 205 (*virCgroupSetBlkioDeviceWriteIopsCB)(virCgroup *group, 206 const char *path, 207 unsigned int wiops); 208 209 typedef int 210 (*virCgroupGetBlkioDeviceWriteIopsCB)(virCgroup *group, 211 const char *path, 212 unsigned int *wiops); 213 214 typedef int 215 (*virCgroupSetBlkioDeviceReadBpsCB)(virCgroup *group, 216 const char *path, 217 unsigned long long rbps); 218 219 typedef int 220 (*virCgroupGetBlkioDeviceReadBpsCB)(virCgroup *group, 221 const char *path, 222 unsigned long long *rbps); 223 224 typedef int 225 (*virCgroupSetBlkioDeviceWriteBpsCB)(virCgroup *group, 226 const char *path, 227 unsigned long long wbps); 228 229 typedef int 230 (*virCgroupGetBlkioDeviceWriteBpsCB)(virCgroup *group, 231 const char *path, 232 unsigned long long *wbps); 233 234 typedef int 235 (*virCgroupSetMemoryCB)(virCgroup *group, 236 unsigned long long kb); 237 238 typedef int 239 (*virCgroupGetMemoryStatCB)(virCgroup *group, 240 unsigned long long *cache, 241 unsigned long long *activeAnon, 242 unsigned long long *inactiveAnon, 243 unsigned long long *activeFile, 244 unsigned long long *inactiveFile, 245 unsigned long long *unevictable); 246 247 typedef int 248 (*virCgroupGetMemoryUsageCB)(virCgroup *group, 249 unsigned long *kb); 250 251 typedef int 252 (*virCgroupSetMemoryHardLimitCB)(virCgroup *group, 253 unsigned long long kb); 254 255 typedef int 256 (*virCgroupGetMemoryHardLimitCB)(virCgroup *group, 257 unsigned long long *kb); 258 259 typedef int 260 (*virCgroupSetMemorySoftLimitCB)(virCgroup *group, 261 unsigned long long kb); 262 263 typedef int 264 (*virCgroupGetMemorySoftLimitCB)(virCgroup *group, 265 unsigned long long *kb); 266 267 typedef int 268 (*virCgroupSetMemSwapHardLimitCB)(virCgroup *group, 269 unsigned long long kb); 270 271 typedef int 272 (*virCgroupGetMemSwapHardLimitCB)(virCgroup *group, 273 unsigned long long *kb); 274 275 typedef int 276 (*virCgroupGetMemSwapUsageCB)(virCgroup *group, 277 unsigned long long *kb); 278 279 typedef int 280 (*virCgroupAllowDeviceCB)(virCgroup *group, 281 char type, 282 int major, 283 int minor, 284 int perms); 285 286 typedef int 287 (*virCgroupDenyDeviceCB)(virCgroup *group, 288 char type, 289 int major, 290 int minor, 291 int perms); 292 293 typedef int 294 (*virCgroupAllowAllDevicesCB)(virCgroup *group, 295 int perms); 296 297 typedef int 298 (*virCgroupDenyAllDevicesCB)(virCgroup *group); 299 300 typedef int 301 (*virCgroupSetCpuSharesCB)(virCgroup *group, 302 unsigned long long shares); 303 304 typedef int 305 (*virCgroupGetCpuSharesCB)(virCgroup *group, 306 unsigned long long *shares); 307 308 typedef int 309 (*virCgroupSetCpuCfsPeriodCB)(virCgroup *group, 310 unsigned long long cfs_period); 311 312 typedef int 313 (*virCgroupGetCpuCfsPeriodCB)(virCgroup *group, 314 unsigned long long *cfs_period); 315 316 typedef int 317 (*virCgroupSetCpuCfsQuotaCB)(virCgroup *group, 318 long long cfs_quota); 319 320 typedef int 321 (*virCgroupGetCpuCfsQuotaCB)(virCgroup *group, 322 long long *cfs_quota); 323 324 typedef bool 325 (*virCgroupSupportsCpuBWCB)(virCgroup *cgroup); 326 327 typedef int 328 (*virCgroupGetCpuacctUsageCB)(virCgroup *group, 329 unsigned long long *usage); 330 331 typedef int 332 (*virCgroupGetCpuacctPercpuUsageCB)(virCgroup *group, 333 char **usage); 334 335 typedef int 336 (*virCgroupGetCpuacctStatCB)(virCgroup *group, 337 unsigned long long *user, 338 unsigned long long *sys); 339 340 typedef int 341 (*virCgroupSetFreezerStateCB)(virCgroup *group, 342 const char *state); 343 344 typedef int 345 (*virCgroupGetFreezerStateCB)(virCgroup *group, 346 char **state); 347 348 typedef int 349 (*virCgroupSetCpusetMemsCB)(virCgroup *group, 350 const char *mems); 351 352 typedef int 353 (*virCgroupGetCpusetMemsCB)(virCgroup *group, 354 char **mems); 355 356 typedef int 357 (*virCgroupSetCpusetMemoryMigrateCB)(virCgroup *group, 358 bool migrate); 359 360 typedef int 361 (*virCgroupGetCpusetMemoryMigrateCB)(virCgroup *group, 362 bool *migrate); 363 364 typedef int 365 (*virCgroupSetCpusetCpusCB)(virCgroup *group, 366 const char *cpus); 367 368 typedef int 369 (*virCgroupGetCpusetCpusCB)(virCgroup *group, 370 char **cpus); 371 372 struct _virCgroupBackend { 373 virCgroupBackendType type; 374 375 /* Mandatory callbacks that need to be implemented for every backend. */ 376 virCgroupAvailableCB available; 377 virCgroupValidateMachineGroupCB validateMachineGroup; 378 virCgroupCopyMountsCB copyMounts; 379 virCgroupCopyPlacementCB copyPlacement; 380 virCgroupDetectMountsCB detectMounts; 381 virCgroupDetectPlacementCB detectPlacement; 382 virCgroupSetPlacementCB setPlacement; 383 virCgroupValidatePlacementCB validatePlacement; 384 virCgroupStealPlacementCB stealPlacement; 385 virCgroupDetectControllersCB detectControllers; 386 virCgroupHasControllerCB hasController; 387 virCgroupGetAnyControllerCB getAnyController; 388 virCgroupPathOfControllerCB pathOfController; 389 virCgroupMakeGroupCB makeGroup; 390 virCgroupExistsCB exists; 391 virCgroupRemoveCB remove; 392 virCgroupAddTaskCB addTask; 393 virCgroupHasEmptyTasksCB hasEmptyTasks; 394 virCgroupKillRecursiveCB killRecursive; 395 virCgroupBindMountCB bindMount; 396 virCgroupSetOwnerCB setOwner; 397 398 /* Optional cgroup controller specific callbacks. */ 399 virCgroupSetBlkioWeightCB setBlkioWeight; 400 virCgroupGetBlkioWeightCB getBlkioWeight; 401 virCgroupGetBlkioIoServicedCB getBlkioIoServiced; 402 virCgroupGetBlkioIoDeviceServicedCB getBlkioIoDeviceServiced; 403 virCgroupSetBlkioDeviceWeightCB setBlkioDeviceWeight; 404 virCgroupGetBlkioDeviceWeightCB getBlkioDeviceWeight; 405 virCgroupSetBlkioDeviceReadIopsCB setBlkioDeviceReadIops; 406 virCgroupGetBlkioDeviceReadIopsCB getBlkioDeviceReadIops; 407 virCgroupSetBlkioDeviceWriteIopsCB setBlkioDeviceWriteIops; 408 virCgroupGetBlkioDeviceWriteIopsCB getBlkioDeviceWriteIops; 409 virCgroupSetBlkioDeviceReadBpsCB setBlkioDeviceReadBps; 410 virCgroupGetBlkioDeviceReadBpsCB getBlkioDeviceReadBps; 411 virCgroupSetBlkioDeviceWriteBpsCB setBlkioDeviceWriteBps; 412 virCgroupGetBlkioDeviceWriteBpsCB getBlkioDeviceWriteBps; 413 414 virCgroupSetMemoryCB setMemory; 415 virCgroupGetMemoryStatCB getMemoryStat; 416 virCgroupGetMemoryUsageCB getMemoryUsage; 417 virCgroupSetMemoryHardLimitCB setMemoryHardLimit; 418 virCgroupGetMemoryHardLimitCB getMemoryHardLimit; 419 virCgroupSetMemorySoftLimitCB setMemorySoftLimit; 420 virCgroupGetMemorySoftLimitCB getMemorySoftLimit; 421 virCgroupSetMemSwapHardLimitCB setMemSwapHardLimit; 422 virCgroupGetMemSwapHardLimitCB getMemSwapHardLimit; 423 virCgroupGetMemSwapUsageCB getMemSwapUsage; 424 425 virCgroupAllowDeviceCB allowDevice; 426 virCgroupDenyDeviceCB denyDevice; 427 virCgroupAllowAllDevicesCB allowAllDevices; 428 virCgroupDenyAllDevicesCB denyAllDevices; 429 430 virCgroupSetCpuSharesCB setCpuShares; 431 virCgroupGetCpuSharesCB getCpuShares; 432 virCgroupSetCpuCfsPeriodCB setCpuCfsPeriod; 433 virCgroupGetCpuCfsPeriodCB getCpuCfsPeriod; 434 virCgroupSetCpuCfsQuotaCB setCpuCfsQuota; 435 virCgroupGetCpuCfsQuotaCB getCpuCfsQuota; 436 virCgroupSupportsCpuBWCB supportsCpuBW; 437 438 virCgroupGetCpuacctUsageCB getCpuacctUsage; 439 virCgroupGetCpuacctPercpuUsageCB getCpuacctPercpuUsage; 440 virCgroupGetCpuacctStatCB getCpuacctStat; 441 442 virCgroupSetFreezerStateCB setFreezerState; 443 virCgroupGetFreezerStateCB getFreezerState; 444 445 virCgroupSetCpusetMemsCB setCpusetMems; 446 virCgroupGetCpusetMemsCB getCpusetMems; 447 virCgroupSetCpusetMemoryMigrateCB setCpusetMemoryMigrate; 448 virCgroupGetCpusetMemoryMigrateCB getCpusetMemoryMigrate; 449 virCgroupSetCpusetCpusCB setCpusetCpus; 450 virCgroupGetCpusetCpusCB getCpusetCpus; 451 }; 452 typedef struct _virCgroupBackend virCgroupBackend; 453 454 void 455 virCgroupBackendRegister(virCgroupBackend *backend); 456 457 virCgroupBackend ** 458 virCgroupBackendGetAll(void); 459 460 virCgroupBackend * 461 virCgroupBackendForController(virCgroup *group, 462 unsigned int controller); 463 464 #define VIR_CGROUP_BACKEND_CALL(group, controller, func, ret, ...) \ 465 do { \ 466 virCgroupBackend *backend = virCgroupBackendForController(group, controller); \ 467 if (!backend) { \ 468 virReportError(VIR_ERR_INTERNAL_ERROR, \ 469 _("failed to get cgroup backend for '%s' controller '%u'"), \ 470 #func, controller); \ 471 return ret; \ 472 } \ 473 if (!backend->func) { \ 474 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, \ 475 _("operation '%s' not supported for backend '%s'"), \ 476 #func, virCgroupBackendTypeToString(backend->type)); \ 477 return ret; \ 478 } \ 479 return backend->func(group, ##__VA_ARGS__); \ 480 } while (0) 481