All of lore.kernel.org
 help / color / mirror / Atom feed
From: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>
To: embedded-pv-devel@lists.xenproject.org
Cc: wei.liu2@citrix.com, stefano.stabellini@eu.citrix.com,
	ian.jackson@eu.citrix.com, ian.campbell@citrix.com,
	xen-devel@lists.xen.org
Subject: [PATCH RFC 3/6] libxl: implementation of PV tty device interface.
Date: Thu, 19 May 2016 17:37:32 +0300	[thread overview]
Message-ID: <1463668655-16778-4-git-send-email-iurii.mykhalskyi@globallogic.com> (raw)
In-Reply-To: <1463668655-16778-1-git-send-email-iurii.mykhalskyi@globallogic.com>

PV tty device interface is implemented in libxl and xl with
full support for device control. No JSON parser for domain
configuration yet.

Signed-off-by: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>
Signed-off-by: Iurii Konovalenko <iurii.konovalenko@globallogic.com>
---
 tools/libxl/libxl.c                  | 282 +++++++++++++++++++++++++++++++++++
 tools/libxl/libxl.h                  |  17 +++
 tools/libxl/libxl_create.c           |  37 ++++-
 tools/libxl/libxl_device.c           |   2 +
 tools/libxl/libxl_internal.h         |  13 +-
 tools/libxl/libxl_types.idl          |  19 +++
 tools/libxl/libxl_types_internal.idl |   1 +
 tools/libxl/libxl_utils.h            |   3 +
 tools/libxl/xl.h                     |   3 +
 tools/libxl/xl_cmdimpl.c             | 160 +++++++++++++++++++-
 tools/libxl/xl_cmdtable.c            |  15 ++
 11 files changed, 549 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index d96172d..1426bf6 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2595,6 +2595,276 @@ exit:
 
 /******************************************************************************/
 
+int libxl__device_vtty_setdefault(libxl__gc *gc, libxl_device_vtty *vtty)
+{
+    int rc;
+
+    rc = libxl__resolve_domid(gc, vtty->backend_domname, &vtty->backend_domid);
+
+    return rc;
+}
+
+static int libxl__device_from_vtty(libxl__gc *gc, uint32_t domid, libxl_device_vtty *vtty, libxl__device *device)
+{
+   device->backend_devid   = vtty->devid;
+   device->backend_domid   = vtty->backend_domid;
+   device->backend_kind    = LIBXL__DEVICE_KIND_VTTY;
+   device->devid           = vtty->devid;
+   device->domid           = domid;
+   device->kind            = LIBXL__DEVICE_KIND_VTTY;
+
+   return 0;
+}
+
+static int libxl__device_vtty_from_xs_be(libxl__gc *gc,
+                                        const char *be_path,
+                                        libxl_device_vtty *vtty)
+{
+    const char *tmp;
+    int rc;
+
+    libxl_device_vtty_init(vtty);
+
+    tmp = READ_BACKEND(gc, "device-id");
+    if (tmp)
+    	vtty->devid = atoi(tmp);
+    else
+    	vtty->devid = 0;
+
+    rc = 0;
+ out:
+    return rc;
+}
+
+int libxl_devid_to_device_vtty(libxl_ctx *ctx, uint32_t domid,
+                              int devid, libxl_device_vtty *vtty)
+{
+    GC_INIT(ctx);
+    char *dompath, *path;
+    int rc = ERROR_FAIL;
+
+    libxl_device_vtty_init(vtty);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    if (!dompath)
+        goto out;
+
+    path = libxl__xs_read(gc, XBT_NULL,
+                          libxl__sprintf(gc, "%s/device/vtty/%d/backend",
+                                         dompath, devid));
+    if (!path)
+        goto out;
+
+    rc = libxl__device_vtty_from_xs_be(gc, path, vtty);
+    if (rc) goto out;
+
+    rc = 0;
+out:
+    GC_FREE;
+    return rc;
+}
+
+void libxl__device_vtty_add(libxl__egc *egc, uint32_t domid, libxl_device_vtty *vtty, libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    flexarray_t *front;
+    flexarray_t *back;
+    libxl__device *device;
+    int rc;
+    xs_transaction_t t = XBT_NULL;
+    libxl_domain_config d_config;
+    libxl_device_vtty vtty_saved;
+    libxl__domain_userdata_lock *lock = NULL;
+
+    libxl_domain_config_init(&d_config);
+    libxl_device_vtty_init(&vtty_saved);
+    libxl_device_vtty_copy(CTX, &vtty_saved, vtty);
+
+    rc = libxl__device_vtty_setdefault(gc, vtty);
+    if (rc) goto out;
+
+    front = flexarray_make(gc, 16, 1);
+    back = flexarray_make(gc, 32, 1);
+
+    if ((vtty->devid = libxl__device_nextid(gc, domid, "vtty")) < 0) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    GCNEW(device);
+    rc = libxl__device_from_vtty(gc, domid, vtty, device);
+    if ( rc != 0 ) goto out;
+
+    flexarray_append(back, "device-id");
+    flexarray_append(back, GCSPRINTF("%d", vtty->devid));
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, GCSPRINTF("%d", domid));
+    flexarray_append(back, "device");
+    flexarray_append(back, vtty->device);
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, GCSPRINTF("%d", 1));
+
+    flexarray_append(front, "device-id");
+    flexarray_append(front, GCSPRINTF("%d", vtty->devid));
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, GCSPRINTF("%d", vtty->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, GCSPRINTF("%d", 1));
+
+    if (aodev->update_json) {
+        lock = libxl__lock_domain_userdata(gc, domid);
+        if (!lock) {
+            rc = ERROR_LOCK_FAIL;
+            goto out;
+        }
+
+        rc = libxl__get_domain_configuration(gc, domid, &d_config);
+        LOG(INFO, "aodev updates JSON, libxl__get_domain_configuration returned %d", rc);
+        if (rc) goto out;
+
+        DEVICE_ADD(vtty, vttys, domid, &vtty_saved, COMPARE_DEVID, &d_config);
+    }
+
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &t);
+        if (rc) goto out;
+
+        rc = libxl__device_exists(gc, t, device);
+        if (rc < 0) goto out;
+        if (rc == 1) {              /* already exists in xenstore */
+            LOG(ERROR, "device already exists in xenstore");
+            aodev->action = LIBXL__DEVICE_ACTION_ADD; /* for error message */
+            rc = ERROR_DEVICE_EXISTS;
+            goto out;
+        }
+
+        if (aodev->update_json) {
+            rc = libxl__set_domain_configuration(gc, domid, &d_config);
+            if (rc) goto out;
+        }
+
+        libxl__device_generic_add(gc, t, device,
+                                  libxl__xs_kvs_of_flexarray(gc, back,
+                                                             back->count),
+                                  libxl__xs_kvs_of_flexarray(gc, front,
+                                                             front->count),
+                                  NULL);
+
+        rc = libxl__xs_transaction_commit(gc, &t);
+
+        if (!rc) break;
+        if (rc < 0) goto out;
+    }
+
+    aodev->dev = device;
+    aodev->action = LIBXL__DEVICE_ACTION_ADD;
+    libxl__wait_device_connection(egc, aodev);
+
+    rc = 0;
+out:
+    libxl__xs_transaction_abort(gc, &t);
+    if (lock) libxl__unlock_domain_userdata(lock);
+    libxl_device_vtty_dispose(&vtty_saved);
+    libxl_domain_config_dispose(&d_config);
+    aodev->rc = rc;
+    if(rc) aodev->callback(egc, aodev);
+    return;
+
+}
+
+libxl_device_vtty *libxl_device_vtty_list(libxl_ctx *ctx, uint32_t domid, int *num)
+{
+    GC_INIT(ctx);
+
+    libxl_device_vtty* vttys = NULL;
+    char* fe_path = NULL;
+    char** dir = NULL;
+    unsigned int ndirs = 0;
+
+    *num = 0;
+
+    fe_path = libxl__sprintf(gc, "%s/device/vtty", libxl__xs_get_dompath(gc, domid));
+    dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs);
+    if (dir && ndirs) {
+       vttys = malloc(sizeof(*vttys) * ndirs);
+       libxl_device_vtty* vtty;
+       libxl_device_vtty* end = vttys + ndirs;
+       for(vtty = vttys; vtty < end; ++vtty, ++dir) {
+          char* tmp;
+
+          libxl_device_vtty_init(vtty);
+
+          vtty->devid = atoi(*dir);
+
+          tmp = libxl__xs_read(gc, XBT_NULL,
+                GCSPRINTF("%s/%s/backend-id",
+                   fe_path, *dir));
+          vtty->backend_domid = atoi(tmp);
+       }
+    }
+    *num = ndirs;
+
+    GC_FREE;
+    return vttys;
+}
+
+int libxl_device_vtty_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_vtty *vtty, libxl_vttyinfo *vttyinfo)
+{
+    GC_INIT(ctx);
+    char *dompath, *vttypath;
+    char *val;
+    int rc = 0;
+
+    libxl_vttyinfo_init(vttyinfo);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    vttyinfo->devid = vtty->devid;
+
+    vttypath = GCSPRINTF("%s/device/vtty/%d", dompath, vttyinfo->devid);
+    vttyinfo->backend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/backend", vttypath), NULL);
+
+    if (!vttyinfo->backend) {
+        goto err;
+    }
+
+    if(!libxl__xs_read(gc, XBT_NULL, vttyinfo->backend)) {
+       goto err;
+    }
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/backend-id", vttypath));
+    vttyinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/state", vttypath));
+    vttyinfo->state = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/event-channel", vttypath));
+    vttyinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/ring-ref", vttypath));
+    vttyinfo->rref = val ? strtoul(val, NULL, 10) : -1;
+
+    vttyinfo->frontend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/frontend", vttyinfo->backend), NULL);
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/frontend-id", vttyinfo->backend));
+    vttyinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    goto exit;
+err:
+    rc = ERROR_FAIL;
+exit:
+    GC_FREE;
+    return rc;
+}
+
+/******************************************************************************/
+
 int libxl__device_vsnd_setdefault(libxl__gc *gc, libxl_device_vsnd *vsnd)
 {
     int rc;
@@ -4749,6 +5019,8 @@ out:
  * libxl_device_vrtc_destroy
  * libxl_device_vsnd_remove
  * libxl_device_vsnd_destroy
+ * libxl_device_vtty_remove
+ * libxl_device_vtty_destroy
  */
 #define DEFINE_DEVICE_REMOVE(type, removedestroy, f)                    \
     int libxl_device_##type##_##removedestroy(libxl_ctx *ctx,           \
@@ -4808,6 +5080,10 @@ DEFINE_DEVICE_REMOVE(vrtc, destroy, 1)
 DEFINE_DEVICE_REMOVE(vsnd, remove, 0)
 DEFINE_DEVICE_REMOVE(vsnd, destroy, 1)
 
+/* vtty */
+DEFINE_DEVICE_REMOVE(vtty, remove, 0)
+DEFINE_DEVICE_REMOVE(vtty, destroy, 1)
+
 /* channel/console hotunplug is not implemented. There are 2 possibilities:
  * 1. add support for secondary consoles to xenconsoled
  * 2. dynamically add/remove qemu chardevs via qmp messages. */
@@ -4823,6 +5099,7 @@ DEFINE_DEVICE_REMOVE(vsnd, destroy, 1)
  * libxl_device_vtpm_add
  * libxl_device_vrtc_add
  * libxl_device_vsnd_add
+ * libxl_device_vtty_add
  */
 
 #define DEFINE_DEVICE_ADD(type)                                         \
@@ -4860,6 +5137,9 @@ DEFINE_DEVICE_ADD(vrtc)
 /* vsnd */
 DEFINE_DEVICE_ADD(vsnd)
 
+/* vtty */
+DEFINE_DEVICE_ADD(vtty)
+
 #undef DEFINE_DEVICE_ADD
 
 /******************************************************************************/
@@ -7381,6 +7661,8 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
 
     MERGE(pci, pcidevs, COMPARE_PCI, {});
 
+    MERGE(vtty, vttys, COMPARE_DEVID, {});
+
     /* Take care of removable device. We maintain invariant in the
      * insert / remove operation so that:
      * 1. if xenstore is "empty" while JSON is not, the result
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 3cb67e2..47829dd 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1468,6 +1468,23 @@ libxl_device_vsnd *libxl_device_vsnd_list(libxl_ctx *ctx, uint32_t domid, int *n
 int libxl_device_vsnd_getinfo(libxl_ctx *ctx, uint32_t domid,
                               libxl_device_vsnd *vsnd, libxl_vsndinfo *vsndinfo);
 
+/* TTY */
+int libxl_device_vtty_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vtty *vtty,
+                          const libxl_asyncop_how *ao_how)
+                          LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vtty_remove(libxl_ctx *ctx, uint32_t domid,
+                             libxl_device_vtty *vtty,
+                             const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vtty_destroy(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vtty *vtty,
+                              const libxl_asyncop_how *ao_how)
+                              LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_vtty *libxl_device_vtty_list(libxl_ctx *ctx, uint32_t domid, int *num);
+int libxl_device_vtty_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vtty *vtty, libxl_vttyinfo *vttyinfo);
+
 /* Keyboard */
 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
                          const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 8ff4178..38d9b12 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -736,6 +736,8 @@ static void domcreate_attach_vtpms(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
 static void domcreate_attach_vrtcs(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
+static void domcreate_attach_vttys(libxl__egc *egc, libxl__multidev *multidev,
+                                   int ret);
 static void domcreate_attach_vsnds(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
 static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *aodevs,
@@ -1429,12 +1431,45 @@ static void domcreate_attach_vrtcs(libxl__egc *egc,
    if (d_config->num_vrtcs > 0) {
        /* Attach vrtcs */
        libxl__multidev_begin(ao, &dcs->multidev);
-       dcs->multidev.callback = domcreate_attach_vsnds;
+       dcs->multidev.callback = domcreate_attach_vttys;
        libxl__add_vrtcs(egc, ao, domid, d_config, &dcs->multidev);
        libxl__multidev_prepared(egc, &dcs->multidev, 0);
        return;
    }
 
+   domcreate_attach_vttys(egc, multidev, 0);
+   return;
+
+error_out:
+   assert(ret);
+   domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_attach_vttys(libxl__egc *egc,
+                                   libxl__multidev *multidev,
+                                   int ret)
+{
+   libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev);
+   STATE_AO_GC(dcs->ao);
+   int domid = dcs->guest_domid;
+
+   libxl_domain_config* const d_config = dcs->guest_config;
+
+   if(ret) {
+       LOG(ERROR, "unable to add vtty devices");
+       goto error_out;
+   }
+
+    /* Plug vtty devices */
+   if (d_config->num_vttys > 0) {
+       /* Attach vttys */
+       libxl__multidev_begin(ao, &dcs->multidev);
+       dcs->multidev.callback = domcreate_attach_vsnds;
+       libxl__add_vttys(egc, ao, domid, d_config, &dcs->multidev);
+       libxl__multidev_prepared(egc, &dcs->multidev, 0);
+       return;
+   }
+
    domcreate_attach_vsnds(egc, multidev, 0);
    return;
 
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 419af16..df50fdb 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -546,6 +546,7 @@ void libxl__multidev_prepared(libxl__egc *egc,
  * libxl__add_vtpms
  * libxl__add_vrtcs
  * libxl__add_vsnds
+ * libxl__add_vttys
  */
 
 #define DEFINE_DEVICES_ADD(type)                                        \
@@ -567,6 +568,7 @@ DEFINE_DEVICES_ADD(nic)
 DEFINE_DEVICES_ADD(vtpm)
 DEFINE_DEVICES_ADD(vrtc)
 DEFINE_DEVICES_ADD(vsnd)
+DEFINE_DEVICES_ADD(vtty)
 
 #undef DEFINE_DEVICES_ADD
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index d78dd79..1bacc73 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -478,7 +478,8 @@ typedef struct {
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VFB || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VKBD || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VRTC || \
-    (dev)->backend_kind == LIBXL__DEVICE_KIND_VSND)
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VSND || \
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VTTY)
 
 #define XC_PCI_BDF             "0x%x, 0x%x, 0x%x, 0x%x"
 #define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
@@ -1190,6 +1191,7 @@ _hidden int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
 _hidden int libxl__device_vtpm_setdefault(libxl__gc *gc, libxl_device_vtpm *vtpm);
 _hidden int libxl__device_vrtc_setdefault(libxl__gc *gc, libxl_device_vrtc *vrtc);
 _hidden int libxl__device_vsnd_setdefault(libxl__gc *gc, libxl_device_vsnd *vsnd);
+_hidden int libxl__device_vtty_setdefault(libxl__gc *gc, libxl_device_vtty *vtty);
 _hidden int libxl__device_vfb_setdefault(libxl__gc *gc, libxl_device_vfb *vfb);
 _hidden int libxl__device_vkb_setdefault(libxl__gc *gc, libxl_device_vkb *vkb);
 _hidden int libxl__device_pci_setdefault(libxl__gc *gc, libxl_device_pci *pci);
@@ -2579,6 +2581,11 @@ _hidden void libxl__device_vsnd_add(libxl__egc *egc, uint32_t domid,
                                     libxl_device_vsnd *vsnd,
                                     libxl__ao_device *aodev);
 
+/* AO operation to connect a tty device */
+_hidden void libxl__device_vtty_add(libxl__egc *egc, uint32_t domid,
+                                    libxl_device_vtty *vtty,
+                                    libxl__ao_device *aodev);
+
 /* Internal function to connect a vkb device */
 _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
                                   libxl_device_vkb *vkb);
@@ -3299,6 +3306,10 @@ _hidden void libxl__add_vrtcs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                              libxl_domain_config *d_config,
                              libxl__multidev *multidev);
 
+_hidden void libxl__add_vttys(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                              libxl_domain_config *d_config,
+                              libxl__multidev *multidev);
+
 _hidden void libxl__add_vsnds(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                              libxl_domain_config *d_config,
                              libxl__multidev *multidev);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 8fa29b1..4477297 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -571,6 +571,13 @@ libxl_device_vsnd = Struct("device_vsnd", [
     ("period_max", integer),
     ])
 
+libxl_device_vtty = Struct("device_vtty", [
+    ("backend_domid", libxl_domid),
+    ("backend_domname", string),
+    ("devid", libxl_devid),
+    ("device", string),
+    ])
+
 libxl_device_disk = Struct("device_disk", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
@@ -660,6 +667,7 @@ libxl_domain_config = Struct("domain_config", [
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
     ("vrtcs", Array(libxl_device_vrtc, "num_vrtcs")),
     ("vsnds", Array(libxl_device_vsnd, "num_vsnds")),
+    ("vttys", Array(libxl_device_vtty, "num_vttys")),
     # a channel manifests as a console with a name,
     # see docs/misc/channels.txt
     ("channels", Array(libxl_device_channel, "num_channels")),
@@ -727,6 +735,17 @@ libxl_vsndinfo = Struct("vsndinfo", [
     ("rref", integer),
     ], dir=DIR_OUT)
 
+libxl_vttyinfo = Struct("vttyinfo", [
+    ("backend", string),
+    ("backend_id", uint32),
+    ("frontend", string),
+    ("frontend_id", uint32),
+    ("devid", libxl_devid),
+    ("state", integer),
+    ("evtch", integer),
+    ("rref", integer),
+    ], dir=DIR_OUT)
+
 libxl_vcpuinfo = Struct("vcpuinfo", [
     ("vcpuid", uint32),
     ("cpu", uint32),
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index ec63e23..182aeee 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -24,6 +24,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (8, "VTPM"),
     (9, "VRTC"),
     (10, "VSND"),
+    (11, "VTTY"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index f6532ce..3d47534 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -83,6 +83,9 @@ int libxl_devid_to_device_vrtc(libxl_ctx *ctx, uint32_t domid,
 int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
                                int devid, libxl_device_vsnd *vsnd);
 
+int libxl_devid_to_device_vtty(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_vtty *vtty);
+
 int libxl_bitmap_alloc(libxl_ctx *ctx, libxl_bitmap *bitmap, int n_bits);
     /* Allocated bimap is from malloc, libxl_bitmap_dispose() to be
      * called by the application when done. */
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 81a78c0..cc990c1 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -88,6 +88,9 @@ int main_vrtcdetach(int argc, char **argv);
 int main_vsndattach(int argc, char **argv);
 int main_vsndlist(int argc, char **argv);
 int main_vsnddetach(int argc, char **argv);
+int main_vttyattach(int argc, char **argv);
+int main_vttylist(int argc, char **argv);
+int main_vttydetach(int argc, char **argv);
 int main_vtpmattach(int argc, char **argv);
 int main_vtpmlist(int argc, char **argv);
 int main_vtpmdetach(int argc, char **argv);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index cb2d8c6..5ac9b81 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1271,7 +1271,7 @@ static void parse_config_data(const char *config_source,
     const char *buf;
     long l, vcpus = 0;
     XLU_Config *config;
-    XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, *vrtcs, *vsnds;
+    XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, *vrtcs, *vttys, *vsnds;
     XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
     int pci_power_mgmt = 0;
@@ -1901,6 +1901,54 @@ static void parse_config_data(const char *config_source,
         }
     }
 
+    if (!xlu_cfg_get_list(config, "vtty", &vttys, 0, 0)) {
+        d_config->num_vttys = 0;
+        d_config->vttys = NULL;
+        while ((buf = xlu_cfg_get_listitem(vttys, d_config->num_vttys)) != NULL) {
+            libxl_device_vtty *vtty;
+            libxl_string_list pairs;
+            char *path = NULL;
+            int len;
+
+            vtty = ARRAY_EXTEND_INIT(d_config->vttys, d_config->num_vttys,
+                                     libxl_device_vtty_init);
+
+            split_string_into_string_list(buf, ",", &pairs);
+            len = libxl_string_list_length(&pairs);
+
+            for (i = 0; i < len; i++) {
+                char *key, *key_untrimmed, *value, *value_untrimmed;
+                int rc;
+                rc = split_string_into_pair(pairs[i], "=",
+                                            &key_untrimmed,
+                                            &value_untrimmed);
+                if (rc != 0) {
+                    fprintf(stderr, "failed to parse vtty configuration: %s",
+                            pairs[i]);
+                    exit(1);
+                }
+                trim(isspace, key_untrimmed, &key);
+                trim(isspace, value_untrimmed, &value);
+
+                if (!strcmp(key, "backendid")) {
+                    vtty->backend_domid = atoi(value);
+                } else if (!strcmp(key, "backend")) {
+                    replace_string(&vtty->backend_domname, value);
+                } else if (!strcmp(key, "devid")) {
+                    vtty->devid = atoi(value);
+                } else if (!strcmp(key, "device")) {
+                    replace_string(&vtty->device, value);
+                }
+                free(key);
+                free(key_untrimmed);
+                free(value);
+                free(value_untrimmed);
+            }
+            libxl_string_list_dispose(&pairs);
+            free(path);
+        }
+    }
+
     if (!xlu_cfg_get_list(config, "vsnd", &vsnds, 0, 0)) {
         d_config->num_vsnds = 0;
         d_config->vsnds = NULL;
@@ -7121,6 +7169,116 @@ int main_vsnddetach(int argc, char **argv)
     return rc;
 }
 
+int main_vttyattach(int argc, char **argv)
+{
+
+    int opt;
+    uint32_t fe_domid;
+    libxl_device_vtty vtty;
+    /*  XLU_Config *config = 0; */
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vtty-attach", 2) {
+        /* No options */
+    }
+
+    if (libxl_domain_qualifier_to_domid(ctx, argv[optind], &fe_domid) < 0) {
+        fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
+        return 1;
+    }
+    optind++;
+
+	if (optind < argc) {
+		replace_string(&vtty.device, argv[optind]);
+	}
+
+    /* TODO: fix this temporary hardcode */
+    vtty.backend_domname = "Domain-D";
+    vtty.backend_domid = 1;
+
+    if (dryrun_only) {
+        char *json = libxl_device_vtty_to_json(ctx, &vtty);
+        printf("vtty: %s\n", json);
+        free(json);
+        if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+        return 0;
+    }
+
+    if (libxl_device_vtty_add(ctx, fe_domid, &vtty, 0)) {
+        fprintf(stderr, "libxl_device_vtty_add failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+int main_vttylist(int argc, char **argv)
+{
+   int opt;
+   int i, nb;
+   libxl_device_vtty *vttys;
+   libxl_vttyinfo vttyinfo;
+
+   SWITCH_FOREACH_OPT(opt, "", NULL, "vtty-list", 1) {
+       /* No options */
+   }
+
+   /* vttyinfo.uuid should be outputted too */
+   printf("%-5s %-3s %-6s %-5s %-6s %-8s %-40s %-40s\n",
+           "Vdev", "BE", "handle", "state", "evt-ch", "ring-ref", "BE-path", "FE-path");
+   for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) {
+       uint32_t domid;
+       if (libxl_domain_qualifier_to_domid(ctx, *argv, &domid) < 0) {
+           fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
+           continue;
+       }
+       vttys = libxl_device_vtty_list(ctx, domid, &nb);
+       if (!vttys) {
+           continue;
+       }
+       for (i=0; i<nb; i++) {
+           if (!libxl_device_vtty_getinfo(ctx, domid, &vttys[i], &vttyinfo)) {
+               /*      Vdev BE   hdl  st   evch rref BE-path FE-path UUID */
+               printf("%-5d %-3d %-6d %-5d %-6d %-8d %-40s %-40s\n",
+                       vttyinfo.devid, vttyinfo.backend_id, vttyinfo.frontend_id,
+                       vttyinfo.state, vttyinfo.evtch, vttyinfo.rref, vttyinfo.backend,
+                       vttyinfo.frontend);
+               libxl_vttyinfo_dispose(&vttyinfo);
+           }
+           libxl_device_vtty_dispose(&vttys[i]);
+       }
+       free(vttys);
+   }
+   return 0;
+}
+
+int main_vttydetach(int argc, char **argv)
+{
+    uint32_t domid, devid;
+    int opt, rc = 0;
+    libxl_device_vtty vtty;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vtty-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    devid = atoi(argv[optind+1]);
+
+    if (libxl_devid_to_device_vtty(ctx, domid, devid, &vtty)) {
+        fprintf(stderr, "Error: Device %s not connected.\n", argv[optind+1]);
+        return 1;
+    }
+
+    rc = libxl_device_vtty_remove(ctx, domid, &vtty, 0);
+    if (rc) {
+        fprintf(stderr, "libxl_device_vtty_remove failed.\n");
+        return 1;
+    }
+
+    libxl_device_vtty_dispose(&vtty);
+    return rc;
+}
+
 int main_vtpmattach(int argc, char **argv)
 {
     int opt;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index 78f0700..7e3a8eb 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -386,6 +386,21 @@ struct cmd_spec cmd_table[] = {
       "Destroy a domain's virtual audio device",
       "<Domain> <DevId|uuid>",
     },
+    { "vtty-attach",
+      &main_vttyattach, 1, 1,
+      "Create a new virtual tty device",
+      "<Domain> <Device>",
+    },
+    { "vtty-list",
+      &main_vttylist, 0, 0,
+      "List virtual tty devices for a domain",
+      "<Domain(s)>",
+    },
+    { "vtty-detach",
+      &main_vttydetach, 0, 1,
+      "Destroy a domain's virtual rtc device",
+      "<Domain> <DevId>",
+    },
     { "vtpm-attach",
       &main_vtpmattach, 1, 1,
       "Create a new virtual TPM device",
-- 
2.8.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  parent reply	other threads:[~2016-05-19 14:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-19 14:37 [PATCH RFC 0/6] Set of PV drivers used by production project Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 1/6] libxl: implementation of PV rtc device interface Iurii Mykhalskyi
2016-05-23 16:45   ` Olaf Hering
2016-06-06 13:37   ` Wei Liu
2016-05-19 14:37 ` [PATCH RFC 2/6] libxl: implementation of PV audio " Iurii Mykhalskyi
2016-05-19 14:37 ` Iurii Mykhalskyi [this message]
2016-05-19 14:37 ` [PATCH RFC 4/6] libxl: implementation of PV event " Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 5/6] libxl: implementation of PV DRM " Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 6/6] libxl: implementation of PV RPMSG " Iurii Mykhalskyi
2016-05-19 17:52 ` [Embedded-pv-devel] [PATCH RFC 0/6] Set of PV drivers used by production project Meng Xu
2016-05-23 11:40 ` Wei Liu
2016-06-02 16:12 ` Wei Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1463668655-16778-4-git-send-email-iurii.mykhalskyi@globallogic.com \
    --to=iurii.mykhalskyi@globallogic.com \
    --cc=embedded-pv-devel@lists.xenproject.org \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.