]> git.proxmox.com Git - qemu-server.git/blobdiff - qmeventd/qmeventd.c
qmeventd: further improve getting VMID from PID
[qemu-server.git] / qmeventd / qmeventd.c
index 499376aec0683198b790c083e5099442bc496e9d..0130103de0575b795f7fb800ac8024f4f93c688d 100644 (file)
@@ -75,14 +75,13 @@ get_pid_from_fd(int fd)
 }
 
 /*
- * reads the vmid from /proc/<pid>/cmdline
- * after the '-id' argument
+ * parses the vmid from the qemu.slice entry of /proc/<pid>/cgroup
  */
 static unsigned long
 get_vmid_from_pid(pid_t pid)
 {
     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) {
        fprintf(stderr, "error during snprintf for %d: %s\n", pid,
                strerror(errno));
@@ -99,41 +98,54 @@ get_vmid_from_pid(pid_t pid)
     }
 
     unsigned long vmid = 0;
-    ssize_t rc = 0;
     char *buf = NULL;
     size_t buflen = 0;
-    while ((rc = getdelim(&buf, &buflen, '\0', fp)) >= 0) {
-       if (!strcmp(buf, "-id")) {
-           break;
+
+    while (getline(&buf, &buflen, fp) >= 0) {
+       char *cgroup_path = strrchr(buf, ':');
+       if (!cgroup_path) {
+           fprintf(stderr, "unexpected cgroup entry %s\n", buf);
+           goto ret;
        }
-    }
+       cgroup_path++;
 
-    if (rc < 0) {
-       goto err;
-    }
+       if (strncmp(cgroup_path, "/qemu.slice/", 12)) {
+           continue;
+       }
 
-    if (getdelim(&buf, &buflen, '\0', fp) >= 0) {
-       if (buf[0] == '-' || buf[0] == '\0') {
-           fprintf(stderr, "invalid vmid %s\n", buf);
+       char *vmid_start = strrchr(buf, '/');
+       if (!vmid_start) {
+           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;
        }
 
        errno = 0;
        char *endptr = NULL;
-       vmid = strtoul(buf, &endptr, 10);
-       if (errno != 0) {
+       vmid = strtoul(vmid_start, &endptr, 10);
+       if (!endptr || strncmp(endptr, ".scope", 6)) {
+           fprintf(stderr, "unexpected cgroup entry %s\n", buf);
            vmid = 0;
-           goto err;
-       } else if (*endptr != '\0') {
-           fprintf(stderr, "invalid vmid %s\n", buf);
+           continue;
+       }
+       if (errno != 0) {
+           fprintf(stderr, "error parsing vmid for %d: %s\n", pid, strerror(errno));
            vmid = 0;
        }
 
        goto ret;
     }
 
-err:
-    fprintf(stderr, "error parsing vmid for %d: %s\n", pid, strerror(errno));
+    if (errno) {
+       fprintf(stderr, "error parsing vmid for %d: %s\n", pid, strerror(errno));
+    } else {
+       fprintf(stderr, "error parsing vmid for %d: no matching qemu.slice cgroup entry\n", pid);
+    }
 
 ret:
     free(buf);
@@ -687,6 +699,9 @@ main(int argc, char *argv[])
 
     for(;;) {
        nevents = epoll_wait(epoll_fd, events, 1, needs_cleanup ? 10*1000 : -1);
+       if (nevents < 0 && errno == EINTR) {
+           continue;
+       }
        bail_neg(nevents, "epoll_wait");
 
        for (int n = 0; n < nevents; n++) {