Support for specifying a path prefix to run inside an LXC
This commit is contained in:
parent
eaff59c2ff
commit
9f9966928a
@ -24,16 +24,19 @@ int parseLxcConfigFile(lxcinfo *lxc, char *filedata) {
|
|||||||
strcpy(lxc->hostname, ptr);
|
strcpy(lxc->hostname, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int readLxcConfig(lxcinfo *lxc, int lxcid) {
|
int readLxcConfig(lxcinfo *lxc, int lxcid, char *pathPrefix) {
|
||||||
char *fname = malloc(1024);
|
char *fname = malloc(1024);
|
||||||
char *buffer = malloc(4096);
|
char *buffer = malloc(4096);
|
||||||
|
|
||||||
sprintf(fname, "/etc/pve/lxc/%d.conf", lxcid);
|
sprintf(fname, "%s/etc/pve/lxc/%d.conf", pathPrefix, lxcid);
|
||||||
FILE *file = fopen(fname, "rb");
|
FILE *file = fopen(fname, "rb");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
printf("Failed to open <%s>: %d\n", fname, errno);
|
fprintf(stderr, "Failed to open <%s>: %d\n", fname, errno);
|
||||||
|
free(buffer);
|
||||||
|
free(fname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fread(buffer, 1, 4096, file);
|
fread(buffer, 1, 4096, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
@ -43,14 +46,17 @@ int readLxcConfig(lxcinfo *lxc, int lxcid) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getInactiveLXCs(lxcinfo **lxcs) {
|
void getInactiveLXCs(lxcinfo **lxcs, char *pathPrefix) {
|
||||||
struct dirent *pDirent;
|
struct dirent *pDirent;
|
||||||
DIR *pDir;
|
DIR *pDir;
|
||||||
|
|
||||||
|
char *fname = malloc(1024);
|
||||||
|
sprintf(fname, "%s/etc/pve/lxc", pathPrefix);
|
||||||
// Ensure we can open directory.
|
// Ensure we can open directory.
|
||||||
pDir = opendir("/etc/pve/lxc");
|
pDir = opendir(fname);
|
||||||
if (pDir == NULL) {
|
if (pDir == NULL) {
|
||||||
printf("Cannot open directory '/etc/pve/lxc'\n");
|
fprintf(stderr, "Cannot open directory '%s'\n", fname);
|
||||||
|
free(fname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,13 +69,14 @@ void getInactiveLXCs(lxcinfo **lxcs) {
|
|||||||
int argc = sscanf(fname, "%d.%s", &lxcid, (char *) extension);
|
int argc = sscanf(fname, "%d.%s", &lxcid, (char *) extension);
|
||||||
// ensure it's an LXC config
|
// ensure it's an LXC config
|
||||||
if (argc != 2 || strcmp((char *) extension, "conf") != 0) continue;
|
if (argc != 2 || strcmp((char *) extension, "conf") != 0) continue;
|
||||||
getLXCInfo(lxcs, lxcid); // don't care about result
|
getLXCInfo(lxcs, lxcid, pathPrefix); // don't care about result
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(pDir);
|
closedir(pDir);
|
||||||
|
free(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
lxcinfo *getLXCInfo(lxcinfo **lxcs, int lxcid) {
|
lxcinfo *getLXCInfo(lxcinfo **lxcs, int lxcid, char *pathPrefix) {
|
||||||
lxcinfo *lxc = *lxcs;
|
lxcinfo *lxc = *lxcs;
|
||||||
while (lxc != NULL) {
|
while (lxc != NULL) {
|
||||||
if (lxc->lxcid == lxcid) return lxc;
|
if (lxc->lxcid == lxcid) return lxc;
|
||||||
@ -80,7 +87,7 @@ lxcinfo *getLXCInfo(lxcinfo **lxcs, int lxcid) {
|
|||||||
lxc->lxcid = lxcid;
|
lxc->lxcid = lxcid;
|
||||||
lxc->running = 0;
|
lxc->running = 0;
|
||||||
|
|
||||||
if (readLxcConfig(lxc, lxcid)) {
|
if (readLxcConfig(lxc, lxcid, pathPrefix)) {
|
||||||
// failed to read LXC
|
// failed to read LXC
|
||||||
free(lxc);
|
free(lxc);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ typedef struct _lxc_info {
|
|||||||
char hostname[128];
|
char hostname[128];
|
||||||
} lxcinfo;
|
} lxcinfo;
|
||||||
|
|
||||||
lxcinfo *getLXCInfo(lxcinfo **lxcs, int lxcid);
|
lxcinfo *getLXCInfo(lxcinfo **lxcs, int lxcid, char *pathPrefix);
|
||||||
void getInactiveLXCs(lxcinfo **lxcs);
|
void getInactiveLXCs(lxcinfo **lxcs, char *pathPrefix);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -240,16 +240,19 @@ nextProcess:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *readProcesses(char *procdir) {
|
char *readProcesses(char *pathPrefix) {
|
||||||
int len;
|
int len;
|
||||||
struct dirent *pDirent;
|
struct dirent *pDirent;
|
||||||
DIR *pDir;
|
DIR *pDir;
|
||||||
|
|
||||||
// Ensure we can open directory.
|
char *procdir = malloc(1024);
|
||||||
|
sprintf(procdir, "%s/proc", pathPrefix);
|
||||||
|
|
||||||
|
// Ensure we can open directory.
|
||||||
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);
|
||||||
|
free(procdir);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +275,7 @@ char *readProcesses(char *procdir) {
|
|||||||
|
|
||||||
while ((pDirent = readdir(pDir)) != NULL) {
|
while ((pDirent = readdir(pDir)) != NULL) {
|
||||||
first = pDirent->d_name[0];
|
first = pDirent->d_name[0];
|
||||||
|
// Ignore directories that aren't PIDs
|
||||||
if (first < '0' || first > '9') continue;
|
if (first < '0' || first > '9') continue;
|
||||||
|
|
||||||
if (cur->visited) {
|
if (cur->visited) {
|
||||||
@ -281,7 +285,7 @@ char *readProcesses(char *procdir) {
|
|||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(fname, "/proc/%s/status", pDirent->d_name);
|
sprintf(fname, "%s/%s/status", procdir, 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);
|
||||||
@ -299,7 +303,7 @@ char *readProcesses(char *procdir) {
|
|||||||
|
|
||||||
if (parseStatFile(cur, buffer)) continue;
|
if (parseStatFile(cur, buffer)) continue;
|
||||||
|
|
||||||
sprintf(fname, "/proc/%s/io", pDirent->d_name);
|
sprintf(fname, "%s/%s/io", procdir, 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);
|
||||||
@ -307,7 +311,7 @@ char *readProcesses(char *procdir) {
|
|||||||
|
|
||||||
if (parseIOFile(cur, buffer)) continue;
|
if (parseIOFile(cur, buffer)) continue;
|
||||||
|
|
||||||
sprintf(fname, "/proc/%s/cpuset", pDirent->d_name);
|
sprintf(fname, "%s/%s/cpuset", procdir, pDirent->d_name);
|
||||||
file = fopen(fname, "rb");
|
file = fopen(fname, "rb");
|
||||||
if (file == NULL) goto nextProcess;
|
if (file == NULL) goto nextProcess;
|
||||||
fread(cur->cpuset, 1, sizeof(cur->cpuset), file);
|
fread(cur->cpuset, 1, sizeof(cur->cpuset), file);
|
||||||
@ -318,7 +322,7 @@ char *readProcesses(char *procdir) {
|
|||||||
if (memcmp(cur->cpuset, lxcTag, strlen(lxcTag)) == 0) {
|
if (memcmp(cur->cpuset, lxcTag, strlen(lxcTag)) == 0) {
|
||||||
// Resides in LXC -- read file and tag
|
// Resides in LXC -- read file and tag
|
||||||
sscanf(cur->cpuset, "/lxc/%d/ns", &cur->lxc);
|
sscanf(cur->cpuset, "/lxc/%d/ns", &cur->lxc);
|
||||||
lxcinfo *lxc = getLXCInfo(&lxcs, cur->lxc);
|
lxcinfo *lxc = getLXCInfo(&lxcs, cur->lxc, pathPrefix);
|
||||||
if (lxc == NULL) {
|
if (lxc == NULL) {
|
||||||
printf("Failed to read LXC config <%d>\n", cur->lxc);
|
printf("Failed to read LXC config <%d>\n", cur->lxc);
|
||||||
} else {
|
} else {
|
||||||
@ -340,7 +344,7 @@ nextProcess:
|
|||||||
|
|
||||||
linkFamily(head);
|
linkFamily(head);
|
||||||
aggregateStats(head);
|
aggregateStats(head);
|
||||||
getInactiveLXCs(&lxcs);
|
getInactiveLXCs(&lxcs, pathPrefix);
|
||||||
|
|
||||||
int clocks = sysconf(_SC_CLK_TCK);
|
int clocks = sysconf(_SC_CLK_TCK);
|
||||||
char *output = malloc(8 * 1024 * 1024);
|
char *output = malloc(8 * 1024 * 1024);
|
||||||
@ -390,6 +394,7 @@ nextProcess:
|
|||||||
}
|
}
|
||||||
|
|
||||||
closedir(pDir);
|
closedir(pDir);
|
||||||
|
free(procdir);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
free(fname);
|
free(fname);
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@ -35,7 +35,7 @@ typedef struct st_process {
|
|||||||
uint64_t cWrite;
|
uint64_t cWrite;
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
char *readProcesses(char *procdir);
|
char *readProcesses(char *pathPrefix);
|
||||||
void aggregateStats(Process *head);
|
void aggregateStats(Process *head);
|
||||||
|
|
||||||
int resetVisits(Process *head);
|
int resetVisits(Process *head);
|
||||||
|
|||||||
36
src/server.c
36
src/server.c
@ -44,8 +44,8 @@ void *self_connector_thread(void *arg) {
|
|||||||
|
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
void handle_client(int client_socket) {
|
void handle_client(int client_socket, char *pathPrefix) {
|
||||||
char *data = readProcesses("/proc");
|
char *data = readProcesses(pathPrefix);
|
||||||
int length = strlen(data);
|
int length = strlen(data);
|
||||||
printf("Got data of length: %d\n", length);
|
printf("Got data of length: %d\n", length);
|
||||||
|
|
||||||
@ -92,22 +92,32 @@ closeConnection:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc == 1) {
|
char *portStr = NULL;
|
||||||
char *buf = readProcesses("/proc");
|
char *pathPrefix = "";
|
||||||
if (buf == NULL) return 1;
|
|
||||||
printf(buf);
|
for (int i=0; i<argc; i++) {
|
||||||
free(buf);
|
if (strcmp("--port", argv[i]) == 0) {
|
||||||
return 0;
|
portStr = argv[++i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp("--path.rootfs", argv[i]) == 0) {
|
||||||
|
pathPrefix = argv[++i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<strlen(argv[1]); i++) {
|
if (portStr == NULL) {
|
||||||
if (argv[1][i] < '0' || argv[1][i] > '9') {
|
fprintf(stderr, "Missing required argument --port\n");
|
||||||
fprintf(stderr, "Argument '%s' is not a valid port", argv[1]);
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<strlen(portStr); i++) {
|
||||||
|
if (portStr[i] < '0' || portStr[i] > '9') {
|
||||||
|
fprintf(stderr, "Argument '%s' is not a valid port\n", portStr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int port = atoi(argv[1]);
|
int port = atoi(portStr);
|
||||||
// Set up signal handling
|
// Set up signal handling
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sa.sa_handler = handle_signal;
|
sa.sa_handler = handle_signal;
|
||||||
@ -166,7 +176,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle the client in a separate function
|
// Handle the client in a separate function
|
||||||
handle_client(client_socket);
|
handle_client(client_socket, pathPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(client_socket);
|
close(client_socket);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user