Я написал программу на C для получения событий производительности, таких как циклы процессора контейнеров Docker. Я имею в виду программу пользовательского пространства на уровне хоста (мониторинг на уровне хоста, а не внутри докера). Я даю pid контейнера докера как запись pid perf_event_open( ), однако у меня всегда 0 в качестве возвращаемого значения. Я протестировал программу для других PID, не поддерживающих докер, например для Firefox, и она работает очень хорошо.
Я установил PERF_FLAG_PID_CGROUP в качестве флага, ничего не изменилось! Вот код:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
int
main(int argc, char **argv)
{
struct perf_event_attr pe;
long long count;
int fd;
fd = open("/sys/fs/cgroup/perf_event/docker/f42c13cd9dd700544fe670e30d0b3216bdceaf01ddc370405618fdecfd10b26d", O_RDONLY);
if (fd == -1)
return 0;
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_CPU_CYCLES;
pe.disabled = 1;
pe.exclude_kernel = 0;
pe.exclude_hv = 0;
fd = perf_event_open(&pe, fd, -1, -1, PERF_FLAG_PID_CGROUP);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
usleep(100);
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
read(fd, &count, sizeof(long long));
printf("Used %lld instructions\n", count);
close(fd);
}
Согласно справочной странице perf_event_open(), я также открываю fd в каталоге контейнера докеров в groupfs. Не работает!
Не могли бы вы помочь мне решить проблему? Спасибо
Обновление: я проверил другие события, например PERF_COUNT_HW_CACHE_REFERENCES, и вижу 0 в качестве возвращаемого значения!
ОС: Ubuntu 16.04
Ядро: 4.15.0-041500-универсальный
Архитектура: X86_64