Added support for LXCs

This commit is contained in:
dan 2025-01-14 03:19:45 -05:00
parent 8e99273b42
commit 471bdb71f3
2 changed files with 71 additions and 26 deletions

View File

@ -15,6 +15,8 @@ typedef struct st_process {
int tgid; int tgid;
int level; int level;
char label[128]; char label[128];
char cpuset[128];
char lxcname[128];
int iskernel; int iskernel;
// statistics - each outputs 1 line per process // statistics - each outputs 1 line per process
uint64_t cpuTime; uint64_t cpuTime;

View File

@ -129,8 +129,8 @@ int parseIOFile(Process *proc, char *filedata) {
return 0; return 0;
} }
int readProcesses(char *procdir) { char *readProcesses(char *procdir) {
int len, rc = 1; int len;
struct dirent *pDirent; struct dirent *pDirent;
DIR *pDir; DIR *pDir;
@ -139,7 +139,7 @@ int readProcesses(char *procdir) {
pDir = opendir(procdir); pDir = opendir(procdir);
if (pDir == NULL) { if (pDir == NULL) {
printf("Cannot open directory '%s'\n", procdir); printf("Cannot open directory '%s'\n", procdir);
return 1; return NULL;
} }
// Process each entry. // Process each entry.
@ -175,6 +175,7 @@ int readProcesses(char *procdir) {
if (parseStatFile(cur, buffer)) continue; if (parseStatFile(cur, buffer)) continue;
sprintf(fname, "/proc/%s/io", pDirent->d_name);
file = fopen(fname, "rb"); file = fopen(fname, "rb");
if (file == NULL) continue; if (file == NULL) continue;
fread(buffer, 1, 4096, file); fread(buffer, 1, 4096, file);
@ -182,6 +183,34 @@ int readProcesses(char *procdir) {
if (parseIOFile(cur, buffer)) continue; if (parseIOFile(cur, buffer)) continue;
sprintf(fname, "/proc/%s/cpuset", pDirent->d_name);
file = fopen(fname, "rb");
if (file == NULL) goto nextProcess;
fread(cur->cpuset, 1, sizeof(cur->cpuset), file);
fclose(file);
strtok(cur->cpuset, "\n\t ");
char *lxcTag = "/lxc/";
if (memcmp(cur->cpuset, lxcTag, strlen(lxcTag)) == 0) {
// Resides in LXC -- read file and tag
sscanf(cur->cpuset, "/lxc/%d/ns", &cur->lxc);
sprintf(fname, "/etc/pve/lxc/%d.conf", cur->lxc);
file = fopen(fname, "rb");
if (file == NULL) goto nextProcess;
fread(buffer, 1, 4096, file);
fclose(file);
char *ptr = strstr(buffer, "hostname:");
ptr += strlen("hostname:");
while (*ptr == ' ') ptr++;
strtok(ptr, "\n\t ");
strcpy(cur->lxcname, ptr);
} else {
cur->lxcname[0] = 0;
cur->lxc = -1;
}
nextProcess:
cur->next = malloc(sizeof(Process)); cur->next = malloc(sizeof(Process));
cur->next->prev = cur; cur->next->prev = cur;
cur = cur->next; cur = cur->next;
@ -193,24 +222,23 @@ int readProcesses(char *procdir) {
cur->next = NULL; cur->next = NULL;
int clocks = sysconf(_SC_CLK_TCK); int clocks = sysconf(_SC_CLK_TCK);
char *output = malloc(8*1024*1024);
char *ptr = output;
cur = head; cur = head;
while (cur != NULL) { while (cur != NULL) {
// create process descriptor // create process descriptor
sprintf(buffer, "pid=\"%d\",ppid=\"%d\",label=\"%s\",kernel=\"%d\"", cur->pid, cur->ppid, cur->label, cur->iskernel); sprintf(buffer, "pid=\"%d\",ppid=\"%d\",label=\"%s\",kernel=\"%d\",ctid=\"%d\",lxc=\"%s\"", cur->pid, cur->ppid, cur->label, cur->iskernel, cur->lxc, cur->lxcname);
printf("proc_cpu_time{%s} %f\n", buffer, (double) cur->cpuTime / clocks); ptr += sprintf(ptr, "proc_cpu_time{%s} %f\n", buffer, (double) cur->cpuTime / clocks);
printf("proc_child_cpu_time{%s} %f\n", buffer, (double) cur->childCpuTime / clocks); ptr += sprintf(ptr, "proc_child_cpu_time{%s} %f\n", buffer, (double) cur->childCpuTime / clocks);
printf("proc_num_threads{%s} %llu\n", buffer, cur->nThreads); ptr += sprintf(ptr, "proc_num_threads{%s} %llu\n", buffer, cur->nThreads);
printf("proc_resident_bytes{%s} %llu\n", buffer, cur->resident); ptr += sprintf(ptr, "proc_resident_bytes{%s} %llu\n", buffer, cur->resident);
printf("proc_swap_bytes{%s} %llu\n", buffer, cur->swap); ptr += sprintf(ptr, "proc_swap_bytes{%s} %llu\n", buffer, cur->swap);
printf("proc_fileio_bytes_written{%s} %llu\n", buffer, cur->written); ptr += sprintf(ptr, "proc_fileio_bytes_written{%s} %llu\n", buffer, cur->written);
printf("proc_fileio_bytes_read{%s} %llu\n", buffer, cur->read); ptr += sprintf(ptr, "proc_fileio_bytes_read{%s} %llu\n", buffer, cur->read);
cur = cur->next; cur = cur->next;
} }
rc = 0;
freeChain:
cur = head; cur = head;
while (cur != NULL) { while (cur != NULL) {
Process *prev = cur; Process *prev = cur;
@ -222,34 +250,49 @@ freeChain:
closedir(pDir); closedir(pDir);
free(buffer); free(buffer);
free(fname); free(fname);
return rc; return output;
} }
#define PORT 9101
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
void handle_client(int client_socket) { void handle_client(int client_socket) {
char *data = readProcesses("/proc");
int length = strlen(data);
printf("Got data of length: %d\n", length);
// HTTP response // HTTP response
const char *http_response = const char *http_response_fmt =
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n" "Content-Type: text/plain\r\n"
"Content-Length: 25\r\n" "Content-Length: %d\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"\r\n" "\r\n%s";
"test{data=\"something\"} 25";
char *http_response = malloc(length + strlen(http_response_fmt) + 20);
if (http_response == NULL) perror("Failed to allocate HTTP response\n");
sprintf(http_response, http_response_fmt, length, data);
// Send the response to the client // Send the response to the client
send(client_socket, http_response, strlen(http_response), 0); send(client_socket, http_response, strlen(http_response), 0);
// Close the client socket // Close the client socket
close(client_socket); close(client_socket);
free(http_response);
free(data);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int port = 9101;
if (argc == 1) { if (argc == 1) {
int rc = readProcesses("/proc"); char *buf = readProcesses("/proc");
return rc; if (buf == NULL) return 4;
printf(buf);
return 0;
} else {
port = atoi(argv[1]);
} }
int server_socket, client_socket; int server_socket, client_socket;
@ -265,7 +308,7 @@ int main(int argc, char *argv[]) {
// Configure the server address // Configure the server address
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT); server_addr.sin_port = htons(port);
// Bind the socket to the specified port // Bind the socket to the specified port
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
@ -281,7 +324,7 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("Server is listening on port %d\n", PORT); printf("Server is listening on port %d\n", port);
// Accept and handle incoming connections // Accept and handle incoming connections
while (1) { while (1) {