qmeventd: extract vmid from cgroup file instead of cmdline

This is the single remaining user of the id argument. The id argument
is a Proxmox-specific extension to QEMU, which we'd like to drop to
reduce our differences with upstream QEMU.

Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
Fiona Ebner 2023-05-24 15:56:50 +02:00 committed by Thomas Lamprecht
parent 5674d19810
commit 502870a04c

View File

@ -75,14 +75,13 @@ get_pid_from_fd(int fd)
} }
/* /*
* reads the vmid from /proc/<pid>/cmdline * parses the vmid from the qemu.slice entry of /proc/<pid>/cgroup
* after the '-id' argument
*/ */
static unsigned long static unsigned long
get_vmid_from_pid(pid_t pid) get_vmid_from_pid(pid_t pid)
{ {
char filename[32] = { 0 }; char filename[32] = { 0 };
int len = snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid); int len = snprintf(filename, sizeof(filename), "/proc/%d/cgroup", pid);
if (len < 0) { if (len < 0) {
fprintf(stderr, "error during snprintf for %d: %s\n", pid, fprintf(stderr, "error during snprintf for %d: %s\n", pid,
strerror(errno)); strerror(errno));
@ -99,41 +98,52 @@ get_vmid_from_pid(pid_t pid)
} }
unsigned long vmid = 0; unsigned long vmid = 0;
ssize_t rc = 0;
char *buf = NULL; char *buf = NULL;
size_t buflen = 0; size_t buflen = 0;
while ((rc = getdelim(&buf, &buflen, '\0', fp)) >= 0) {
if (!strcmp(buf, "-id")) { while (getline(&buf, &buflen, fp) >= 0) {
break; char *cgroup_path = strrchr(buf, ':');
if (!cgroup_path) {
fprintf(stderr, "unexpected cgroup entry %s\n", buf);
goto ret;
} }
} cgroup_path++;
if (rc < 0) { if (strncmp(cgroup_path, "/qemu.slice", 11)) {
goto err; continue;
} }
if (getdelim(&buf, &buflen, '\0', fp) >= 0) { char *vmid_start = strrchr(buf, '/');
if (buf[0] == '-' || buf[0] == '\0') { if (!vmid_start) {
fprintf(stderr, "invalid vmid %s\n", buf); fprintf(stderr, "unexpected cgroup entry %s\n", buf);
goto ret;
}
vmid_start++;
if (vmid_start[0] == '-' || vmid_start[0] == '\0') {
fprintf(stderr, "invalid vmid in cgroup entry %s\n", buf);
goto ret; goto ret;
} }
errno = 0; errno = 0;
char *endptr = NULL; char *endptr = NULL;
vmid = strtoul(buf, &endptr, 10); vmid = strtoul(vmid_start, &endptr, 10);
if (errno != 0) { if (errno != 0) {
fprintf(stderr, "error parsing vmid for %d: %s\n", pid, strerror(errno));
vmid = 0; vmid = 0;
goto err; } else if (*endptr != '.') {
} else if (*endptr != '\0') { fprintf(stderr, "unexpected cgroup entry %s\n", buf);
fprintf(stderr, "invalid vmid %s\n", buf);
vmid = 0; vmid = 0;
} }
goto ret; goto ret;
} }
err: if (errno) {
fprintf(stderr, "error parsing vmid for %d: %s\n", pid, strerror(errno)); fprintf(stderr, "error parsing vmid for %d: %s\n", pid, strerror(errno));
} else {
fprintf(stderr, "error parsing vmid for %d: no qemu.slice cgroup entry\n", pid);
}
ret: ret:
free(buf); free(buf);