diff options
Diffstat (limited to 'auto-virtserial-guest.c')
-rw-r--r-- | auto-virtserial-guest.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/auto-virtserial-guest.c b/auto-virtserial-guest.c index 8f984f4..901cfc4 100644 --- a/auto-virtserial-guest.c +++ b/auto-virtserial-guest.c @@ -42,6 +42,8 @@ static int g_fd; static int g_bigfile_fd; /* The length to read / write. Set by the length message. Unset at close */ static int g_length; +/* The 'name' field in the debugfs port info */ +static char g_sysfs_name[1024]; static char *get_port_dev(unsigned int nr) { @@ -221,6 +223,64 @@ static int send_csum(int nr) return ret; } +static int check_sysfs(int nr) +{ + char filename[1024]; + char *str; + int fd, ret; + + sprintf(filename, "/sys/kernel/debug/virtio-console/vcon%u", nr); + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + ret = read(fd, g_sysfs_name, 1024); + if (ret < 0) { + ret = -errno; + goto out_close; + } + str = strstr(g_sysfs_name, "name: "); + if (!str) { + ret = -ERANGE; + goto out_close; + } + ret = 0; + +out_close: + close(fd); + return ret; +} + +static int check_udev(int nr) +{ + char filename[1024], buf[1024]; + char *str; + int ret, i; + + str = strstr(g_sysfs_name, "name: "); + str += 6; /* Skip 'name: ' */ + for (i = 0; *str && *str != '\n'; i++, str++) + buf[i] = *str; + + buf[i] = 0; + sprintf(filename, "/dev/virtio-console/%s", buf); + ret = readlink(filename, buf, 1024); + if (ret < 0) { + ret = -errno; + goto out; + } + sprintf(filename, "../vcon%u", nr); + for (i = 0; i < ret; i++) { + if (buf[i] != filename[i]) { + ret = -ERANGE; + break; + } + } + ret = 0; +out: + return ret; +} + static void send_report(int cfd, int ret) { struct guest_packet gpkt; @@ -327,6 +387,14 @@ back_to_open: ret = send_csum(gpkt.value); send_report(cfd, ret); break; + case KEY_CHECK_SYSFS: + ret = check_sysfs(gpkt.value); + send_report(cfd, ret); + break; + case KEY_CHECK_UDEV: + ret = check_udev(gpkt.value); + send_report(cfd, ret); + break; } } return 0; |