1
0
Prechádzať zdrojové kódy

pass all new usb devices to vm

B Thibault 7 rokov pred
rodič
commit
d20691a349
3 zmenil súbory, kde vykonal 143 pridanie a 0 odobranie
  1. 2 0
      .gitignore
  2. 22 0
      Makefile
  3. 119 0
      main.c

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+*.o
+/pve-hubhotplug

+ 22 - 0
Makefile

@@ -0,0 +1,22 @@
+
+SRC=	main.c
+
+OBJ=	$(SRC:.c=.o)
+
+NAME=	pve-hubhotplug
+
+$(NAME):	all
+
+all: $(OBJ)
+	$(CC) $(OBJ) -o $(NAME) $(LDFLAGS)
+
+clean:
+	$(RM) $(OBJ)
+
+fclean:	clean
+	$(RM) $(NAME)
+
+re:	fclean all
+
+.PHONY:	all clean fclean re
+

+ 119 - 0
main.c

@@ -0,0 +1,119 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+void errExit(const char *err)
+{
+    fprintf(stderr, "%s\n", err);
+    exit(1);
+}
+
+char *addDevice(const char *bus, const char *dev, const char *vmid)
+{
+    DIR *dirfd = opendir("/sys/bus/usb/devices/");
+
+    if (dirfd)
+    {
+        struct dirent *dirEntry;
+        char *devaddr = NULL;
+        char dirStartWith[32];
+        snprintf(dirStartWith, 32, "%s-", bus);
+
+        while (dirEntry = readdir(dirfd))
+        {
+            if (strncmp(dirStartWith, dirEntry->d_name, strlen(dirStartWith)))
+                continue;
+            char path[1024];
+            snprintf(path, 1024, "/sys/bus/usb/devices/%s/devnum", dirEntry->d_name);
+            int fic = open(path, O_RDONLY);
+            if (fic >= 0)
+            {
+                char devnum[32];
+                int rd = read(fic, devnum, 32);
+                close(fic);
+                if (rd)
+                    devnum[rd -1] = 0;
+                printf("{cmp %s vs %s at %s}\n", devnum, dev, dirEntry->d_name);
+                if (!strcmp(devnum, dev))
+                {
+                    devaddr = strdup(dirEntry->d_name +strlen(dirStartWith));
+                    printf("Found device %s\n", dirEntry->d_name);
+                    break;
+                }
+            }
+        }
+        closedir(dirfd);
+        if (devaddr)
+        {
+            char *res = malloc(sizeof(*res) * 1024);
+            snprintf(res, 1024, "echo device_add usb-host,hostbus=%s,hostport=%s,id=hubhotplug-%s-%s | qm monitor %s\n", bus, devaddr, bus, dev, vmid);
+            free(devaddr);
+            return res;
+        }
+    }
+    return NULL;
+}
+
+char *delDevice(const char *bus, const char *dev, const char *vmid)
+{
+    char *res = malloc(sizeof(*res) * 1024);
+    snprintf(res, 1024, "echo device_del hubhotplug-%s-%s | qm monitor %s\n", bus, dev, vmid);
+    return res;
+}
+
+int main(int ac, char **av)
+{
+    const char *vmid = av[1];
+    const char *devtypeStr = getenv("DEVTYPE");
+    const char *actionStr = getenv("ACTION");
+    const char *busNumStr = getenv("BUSNUM");
+    const char *devNumStr = getenv("DEVNUM");
+
+    if (!vmid)
+    {
+        fprintf(stderr, "Usage: %s VM-id\n", *av);
+        exit(1);
+    }
+    if (!devtypeStr)
+        errExit("Missing udev DEVTYPE");
+    if (!actionStr)
+        errExit("Missing udev ACTION");
+    if (!busNumStr)
+        errExit("Missing udev BUSNUM");
+    if (!devNumStr)
+        errExit("Missing udev DEVNUM");
+
+    if (strcmp(devtypeStr, "usb_device"))
+        errExit("Ignoring, devtype not matched");
+
+    while (*busNumStr == '0')
+        ++busNumStr;
+    while (*devNumStr == '0')
+        ++devNumStr;
+
+    char *action;
+    FILE *f = fopen("/tmp/log", "w+");
+    fprintf(f, "%s:%s\n", busNumStr, devNumStr);
+    if (!strcmp(actionStr, "add"))
+        action = addDevice(busNumStr, devNumStr, vmid);
+    else if (!strcmp(actionStr, "remove"))
+        action = delDevice(busNumStr, devNumStr, vmid);
+    else
+        errExit("Invalid ACTION");
+
+    if (action)
+    {
+        fprintf(f, ">>> %s\n", action);
+        system(action);
+        free(action);
+    }
+    fclose(f);
+}
+