forked from OpenCloudOS/perf-prof
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvcpu_info.c
85 lines (69 loc) · 2.07 KB
/
vcpu_info.c
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <vcpu_info.h>
struct vcpu_info *vcpu_info_new(const char *vm)
{
char buff[512];
FILE *info = NULL;
struct vcpu_info *vcpu = NULL;
int nr_vcpu = 0;
snprintf(buff, sizeof(buff), "virsh qemu-monitor-command %s --hmp info cpus", vm);
info = popen(buff, "r");
if (!info)
goto cleanup;
/*
* This is the gross format we're about to parse :-{
*
* (qemu) info cpus
* * CPU #0: pc=0x00000000000f0c4a thread_id=30019
* CPU #1: pc=0x00000000fffffff0 thread_id=30020
* CPU #2: pc=0x00000000fffffff0 (halted) thread_id=30021
*
*/
while (fgets(buff, sizeof(buff), info)) {
char *offset = NULL;
char *end = NULL;
long int cpuid = -1;
long int tid = 0;
int len = strlen(buff);
if (len == 0 || (len == 1 && buff[0] == '\n'))
continue;
/* extract cpu number */
if ((offset = strstr(buff, "#")) == NULL)
goto cleanup;
cpuid = strtol(offset + strlen("#"), &end, 0);
if (cpuid == LONG_MIN || cpuid == LONG_MAX)
goto cleanup;
if (end == NULL || *end != ':')
goto cleanup;
/* Extract host Thread ID */
if ((offset = strstr(end, "thread_id=")) == NULL)
goto cleanup;
tid = strtol(offset + strlen("thread_id="), &end, 0);
if (cpuid == LONG_MIN || cpuid == LONG_MAX)
goto cleanup;
if (end == NULL)
goto cleanup;
if (cpuid >= nr_vcpu) {
vcpu = realloc(vcpu, sizeof(int) * (cpuid + 32));
if (!vcpu)
goto cleanup;
memset(&vcpu->thread_id[nr_vcpu], 0, sizeof(int) * (cpuid + 32 - nr_vcpu));
nr_vcpu = cpuid + 32;
}
vcpu->thread_id[cpuid] = (int)tid;
}
pclose(info);
return vcpu;
cleanup:
if (info) pclose(info);
if (vcpu) free(vcpu);
return NULL;
}
void vcpu_info_free(struct vcpu_info *vcpu)
{
free(vcpu);
}