[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 2/5] libxl: add vsnd list and info



From: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx>

Add getting vsnd list and info API

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx>
---
 tools/libxl/libxl.h         |  10 +
 tools/libxl/libxl_types.idl |  19 ++
 tools/libxl/libxl_utils.h   |   3 +
 tools/libxl/libxl_vsnd.c    | 365 +++++++++++++++++++++++++++++++++++-
 4 files changed, 394 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index a312166b48..bfc788594c 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -2014,6 +2014,16 @@ int libxl_device_vsnd_destroy(libxl_ctx *ctx, uint32_t 
domid,
                               const libxl_asyncop_how *ao_how)
                               LIBXL_EXTERNAL_CALLERS_ONLY;
 
+libxl_device_vsnd *libxl_device_vsnd_list(libxl_ctx *ctx,
+                                          uint32_t domid, int *num)
+                                          LIBXL_EXTERNAL_CALLERS_ONLY;
+void libxl_device_vsnd_list_free(libxl_device_vsnd* list, int num)
+                                 LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vsnd_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vsnd *vsnd,
+                              libxl_vsndinfo *vsndlinfo)
+                              LIBXL_EXTERNAL_CALLERS_ONLY;
+
 /* 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_types.idl b/tools/libxl/libxl_types.idl
index 4218bf466f..46fa64f88d 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -1019,6 +1019,25 @@ libxl_vdisplinfo = Struct("vdisplinfo", [
     ("connectors", Array(libxl_connectorinfo, "num_connectors"))
     ], dir=DIR_OUT)
 
+libxl_streaminfo = Struct("streaminfo", [
+    ("req_evtch", integer),
+    ("req_rref", integer)
+    ])
+
+libxl_pcminfo = Struct("pcminfo", [
+    ("streams", Array(libxl_streaminfo, "num_vsnd_streams"))
+    ])
+
+libxl_vsndinfo = Struct("vsndinfo", [
+    ("backend", string),
+    ("backend_id", uint32),
+    ("frontend", string),
+    ("frontend_id", uint32),
+    ("devid", libxl_devid),
+    ("state", integer),
+    ("pcms", Array(libxl_pcminfo, "num_vsnd_pcms"))
+    ])
+
 # NUMA node characteristics: size and free are how much memory it has, and how
 # much of it is free, respectively. dists is an array of distances from this
 # node to each other node.
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 9e743dc598..5455752c6e 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -82,6 +82,9 @@ int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t 
domid,
 int libxl_devid_to_device_vdispl(libxl_ctx *ctx, uint32_t domid,
                                  int devid, libxl_device_vdispl *vdispl);
 
+int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_vsnd *vsnd);
+
 int libxl_ctrlport_to_device_usbdev(libxl_ctx *ctx, uint32_t domid,
                                     int ctrl, int port,
                                     libxl_device_usbdev *usbdev);
diff --git a/tools/libxl/libxl_vsnd.c b/tools/libxl/libxl_vsnd.c
index 9590a7cae9..cf46e3ddb1 100644
--- a/tools/libxl/libxl_vsnd.c
+++ b/tools/libxl/libxl_vsnd.c
@@ -38,22 +38,243 @@ static int libxl__device_from_vsnd(libxl__gc *gc, uint32_t 
domid,
    return 0;
 }
 
+static int libxl__sample_rates_from_string(libxl__gc *gc, const char *str,
+                                           libxl_vsnd_params *params)
+{
+    char *tmp = libxl__strdup(gc, str);
+
+    params->num_sample_rates = 0;
+    params->sample_rates = NULL;
+
+    char *p = strtok(tmp, " ,");
+
+    while (p != NULL) {
+        params->sample_rates = libxl__realloc(NOGC, params->sample_rates,
+                                              sizeof(*params->sample_rates) *
+                                              (params->num_sample_rates + 1));
+        params->sample_rates[params->num_sample_rates++] = strtoul(p, NULL, 0);
+        p = strtok(NULL, " ,");
+    }
+
+    return 0;
+}
+
+static int libxl__sample_formats_from_string(libxl__gc *gc, const char *str,
+                                             libxl_vsnd_params *params)
+{
+    int rc;
+    char *tmp = libxl__strdup(gc, str);
+
+    params->num_sample_formats = 0;
+    params->sample_formats = NULL;
+
+    char *p = strtok(tmp, " ,");
+
+    while (p != NULL) {
+        params->sample_formats = libxl__realloc(NOGC, params->sample_formats,
+                                                
sizeof(*params->sample_formats) *
+                                                (params->num_sample_formats + 
1));
+
+        libxl_vsnd_pcm_format format;
+
+        rc = libxl_vsnd_pcm_format_from_string(p, &format);
+        if (rc) goto out;
+
+        params->sample_formats[params->num_sample_formats++] = format;
+        p = strtok(NULL, " ,");
+    }
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
+static int libxl__params_from_xenstore(libxl__gc *gc, const char *path,
+                                       libxl_vsnd_params *params)
+{
+    const char *tmp;
+    int rc;
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/"XENSND_FIELD_SAMPLE_RATES,
+                                          path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        rc = libxl__sample_rates_from_string(gc, tmp, params);
+        if (rc) goto out;
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/"XENSND_FIELD_SAMPLE_FORMATS,
+                                          path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        rc = libxl__sample_formats_from_string(gc, tmp, params);
+        if (rc) goto out;
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                 GCSPRINTF("%s/"XENSND_FIELD_CHANNELS_MIN,
+                                           path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        params->channels_min = strtoul(tmp, NULL, 0);
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                 GCSPRINTF("%s/"XENSND_FIELD_CHANNELS_MAX,
+                                           path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        params->channels_max = strtoul(tmp, NULL, 0);
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                 GCSPRINTF("%s/"XENSND_FIELD_BUFFER_SIZE,
+                                           path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        params->buffer_size = strtoul(tmp, NULL, 0);
+    }
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
+static int libxl__stream_from_xenstore(libxl__gc *gc, const char *path,
+                                       libxl_vsnd_stream *stream)
+{
+    const char *tmp;
+    int rc;
+
+    stream->unique_id = xs_read(CTX->xsh, XBT_NULL,
+                         GCSPRINTF("%s/"XENSND_FIELD_STREAM_UNIQUE_ID,
+                         path), NULL);
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/"XENSND_FIELD_TYPE,
+                                          path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        libxl_vsnd_stream_type type;
+
+        rc = libxl_vsnd_stream_type_from_string(tmp, &type);
+        if (rc) goto out;
+
+        stream->type = type;
+    }
+
+    rc = libxl__params_from_xenstore(gc, path, &stream->params);
+    if (rc) goto out;
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
+static int libxl__pcm_from_xenstore(libxl__gc *gc, const char *path,
+                                    libxl_vsnd_pcm *pcm)
+{
+    const char *tmp;
+    int rc;
+
+    pcm->name = xs_read(CTX->xsh, XBT_NULL,
+                        GCSPRINTF("%s/"XENSND_FIELD_DEVICE_NAME, path), NULL);
+
+    rc = libxl__params_from_xenstore(gc, path, &pcm->params);
+
+    pcm->streams = NULL;
+    pcm->num_vsnd_streams = 0;
+
+    do {
+        char *stream_path = GCSPRINTF("%s/%d", path, pcm->num_vsnd_streams);
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL, stream_path, &tmp);
+        if (rc) goto out;
+
+        if (tmp) {
+            pcm->streams = libxl__realloc(NOGC, pcm->streams,
+                                          sizeof(*pcm->streams) *
+                                          (++pcm->num_vsnd_streams));
+
+            libxl_vsnd_stream_init(&pcm->streams[pcm->num_vsnd_streams - 1]);
+
+            rc = libxl__stream_from_xenstore(gc, stream_path,
+                                             
&pcm->streams[pcm->num_vsnd_streams
+                                             - 1]);
+            if (rc) goto out;
+        }
+    } while (tmp);
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
 static int libxl__vsnd_from_xenstore(libxl__gc *gc, const char *libxl_path,
                                      libxl_devid devid,
                                      libxl_device_vsnd *vsnd)
 {
-    const char *be_path;
+    const char *tmp;
+    const char *fe_path;
     int rc;
 
     vsnd->devid = devid;
     rc = libxl__xs_read_mandatory(gc, XBT_NULL,
                                   GCSPRINTF("%s/backend", libxl_path),
-                                  &be_path);
+                                  &tmp);
+    if (rc) goto out;
+
+    rc = libxl__backendpath_parse_domid(gc, tmp, &vsnd->backend_domid);
     if (rc) goto out;
 
-    rc = libxl__backendpath_parse_domid(gc, be_path, &vsnd->backend_domid);
+    rc = libxl__xs_read_mandatory(gc, XBT_NULL,
+                                  GCSPRINTF("%s/frontend", libxl_path),
+                                  &fe_path);
     if (rc) goto out;
 
+    vsnd->short_name = xs_read(CTX->xsh, XBT_NULL,
+                               GCSPRINTF("%s/"XENSND_FIELD_VCARD_SHORT_NAME,
+                               fe_path), NULL);
+
+    vsnd->long_name = xs_read(CTX->xsh, XBT_NULL,
+                              GCSPRINTF("%s/"XENSND_FIELD_VCARD_LONG_NAME,
+                              fe_path), NULL);
+
+    rc = libxl__params_from_xenstore(gc, fe_path, &vsnd->params);
+
+    vsnd->pcms = NULL;
+    vsnd->num_vsnd_pcms = 0;
+
+    do {
+        char *pcm_path = GCSPRINTF("%s/%d", fe_path, vsnd->num_vsnd_pcms);
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL, pcm_path, &tmp);
+        if (rc) goto out;
+
+        if (tmp) {
+            vsnd->pcms = libxl__realloc(NOGC, vsnd->pcms, sizeof(*vsnd->pcms) *
+                                        (++vsnd->num_vsnd_pcms));
+
+            libxl_vsnd_pcm_init(&vsnd->pcms[vsnd->num_vsnd_pcms - 1]);
+
+            rc = libxl__pcm_from_xenstore(gc, pcm_path,
+                                          &vsnd->pcms[vsnd->num_vsnd_pcms - 
1]);
+            if (rc) goto out;
+        }
+    } while (tmp);
+
     rc = 0;
 
 out:
@@ -303,11 +524,149 @@ out:
     return rc;
 }
 
+static int libxl__device_stream_getinfo(libxl__gc *gc, const char *path,
+                                        libxl_vsnd_pcm* pcm,
+                                        libxl_pcminfo *info)
+{
+    const char *tmp;
+    int i;
+    int rc;
+
+    info->num_vsnd_streams = pcm->num_vsnd_streams;
+    info->streams = libxl__malloc(NOGC, sizeof(*info->streams) * 
info->num_vsnd_streams);
+
+    for (i = 0; i < info->num_vsnd_streams; i++)
+    {
+        libxl_streaminfo_init(&info->streams[i]);
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                    GCSPRINTF("%s/%d/"XENSND_FIELD_RING_REF,
+                                    path, i), &tmp);
+        if (rc) goto out;
+
+        info->streams[i].req_rref = tmp ? strtoul(tmp, NULL, 10) : -1;
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                    GCSPRINTF("%s/%d/"XENSND_FIELD_EVT_CHNL,
+                                    path, i), &tmp);
+        if (rc) goto out;
+
+        info->streams[i].req_evtch = tmp ? strtoul(tmp, NULL, 10) : -1;
+    }
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
+static int libxl__device_pcm_getinfo(libxl__gc *gc, const char *path,
+                                     libxl_device_vsnd *vsnd,
+                                     libxl_vsndinfo *info)
+{
+    int i;
+    int rc;
+
+    info->num_vsnd_pcms = vsnd->num_vsnd_pcms;
+    info->pcms = libxl__malloc(NOGC, sizeof(*info->pcms) * 
info->num_vsnd_pcms);
+
+    for (i = 0; i < info->num_vsnd_pcms; i++)
+    {
+        libxl_pcminfo_init(&info->pcms[i]);
+
+        rc = libxl__device_stream_getinfo(gc, GCSPRINTF("%s/%d", path, i),
+                                          &vsnd->pcms[i], &info->pcms[i]);
+        if (rc) goto out;
+    }
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
+int libxl_device_vsnd_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vsnd *vsnd,
+                              libxl_vsndinfo *info)
+{
+    GC_INIT(ctx);
+    char *libxl_path, *dompath, *devpath;
+    const char *val;
+    int rc;
+
+    libxl_vsndinfo_init(info);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    info->devid = vsnd->devid;
+
+    devpath = libxl__domain_device_frontend_path(gc, domid, info->devid,
+                                                 LIBXL__DEVICE_KIND_VSND);
+    libxl_path = libxl__domain_device_libxl_path(gc, domid, info->devid,
+                                                 LIBXL__DEVICE_KIND_VSND);
+
+    info->backend = xs_read(ctx->xsh, XBT_NULL,
+                            GCSPRINTF("%s/backend", libxl_path), NULL);
+
+    rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id);
+    if (rc) goto out;
+
+    val = xs_read(ctx->xsh, XBT_NULL, GCSPRINTF("%s/state", devpath), NULL);
+
+    info->state = val ? strtoul(val, NULL, 10) : -1;
+
+    info->frontend = xs_read(ctx->xsh, XBT_NULL,
+                             GCSPRINTF("%s/frontend", libxl_path), NULL);
+
+    info->frontend_id = domid;
+
+    rc = libxl__device_pcm_getinfo(gc, devpath, vsnd, info);
+    if (rc) goto out;
+
+    rc = 0;
+
+out:
+     GC_FREE;
+     return rc;
+}
+
+int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_vsnd *vsnd)
+{
+    GC_INIT(ctx);
+
+    libxl_device_vsnd *vsnds = NULL;
+    int n, i;
+    int rc;
+
+    libxl_device_vsnd_init(vsnd);
+
+    vsnds = libxl__device_list(gc, &libxl__vsnd_devtype, domid, &n);
+
+    if (!vsnds) { rc = ERROR_NOTFOUND; goto out; }
+
+    for (i = 0; i < n; ++i) {
+        if (devid == vsnds[i].devid) {
+            libxl_device_vsnd_copy(ctx, vsnd, &vsnds[i]);
+            rc = 0;
+            goto out;
+        }
+    }
+
+    rc = ERROR_NOTFOUND;
+
+out:
+    if (vsnds)
+        libxl__device_list_free(&libxl__vsnd_devtype, vsnds, n);
+
+    GC_FREE;
+    return rc;
+}
+
 static LIBXL_DEFINE_UPDATE_DEVID(vsnd)
 static LIBXL_DEFINE_DEVICES_ADD(vsnd)
 
 LIBXL_DEFINE_DEVICE_ADD(vsnd)
 LIBXL_DEFINE_DEVICE_REMOVE(vsnd)
+LIBXL_DEFINE_DEVICE_LIST(vsnd)
 
 DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND,
     .update_config = (device_update_config_fn_t) libxl__update_config_vsnd,
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.