summaryrefslogtreecommitdiffstats
path: root/auto-virtserial-guest.c
diff options
context:
space:
mode:
Diffstat (limited to 'auto-virtserial-guest.c')
-rw-r--r--auto-virtserial-guest.c68
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;