[Libvirt-cim] [PATCH 4/8] libxkutil: Console Support

John Ferlan jferlan at redhat.com
Tue Sep 10 20:38:27 UTC 2013


On 09/05/2013 11:36 AM, Viktor Mihajlovski wrote:
> From: Thilo Boehm <tboehm at linux.vnet.ibm.com>
> 
> Added data types for the representation of console devices and their
> source type specific properties.
> Further, implemented libvirt XML parsing and generation of console
> device XML.
> 
> Signed-off-by: Thilo Boehm <tboehm at linux.vnet.ibm.com>
> Signed-off-by: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>
> Reviewed-by: Boris Fiuczynski <fiuczy at linux.vnet.ibm.com>
> ---
>  libxkutil/device_parsing.c |  316 ++++++++++++++++++++++++++++++++++++++++++--
>  libxkutil/device_parsing.h |   43 +++++-
>  libxkutil/xmlgen.c         |  191 +++++++++++++++++++++++++-
>  src/svpc_types.h           |    5 +-
>  4 files changed, 543 insertions(+), 12 deletions(-)
> 
> diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
> index fa9f998..06acbac 100644
> --- a/libxkutil/device_parsing.c
> +++ b/libxkutil/device_parsing.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright IBM Corp. 2007
> + * Copyright IBM Corp. 2007, 2013
>   *
>   * Authors:
>   *  Dan Smith <danms at us.ibm.com>
> @@ -41,6 +41,11 @@
>  #define NET_XPATH       (xmlChar *)"/domain/devices/interface"
>  #define EMU_XPATH       (xmlChar *)"/domain/devices/emulator"
>  #define MEM_XPATH       (xmlChar *)"/domain/memory | /domain/currentMemory"
> +#define CONSOLE_XPATH   (xmlChar *)"/domain/devices/console"
> +/*
> + * To be backward compatible, serial and console is
> + * still part of the graphics.
> + */
>  #define GRAPHICS_XPATH  (xmlChar *)"/domain/devices/graphics | "\
>          "/domain/devices/console | /domain/devices/serial"
>  #define INPUT_XPATH     (xmlChar *)"/domain/devices/input"
> @@ -50,6 +55,11 @@
>  
>  #define MAX(a,b) (((a)>(b))?(a):(b))
>  
> +#define DUP_FIELD(d, s, f) do {                         \
> +                if ((s)->f != NULL)                     \
> +                        (d)->f = strdup((s)->f);        \
> +        } while (0);
> +
>  /* Device parse function */
>  typedef int (*dev_parse_func_t)(xmlNode *, struct virt_device **);
>  
> @@ -133,6 +143,140 @@ static void cleanup_graphics_device(struct graphics_device *dev)
>          free(dev->type);
>  }
>  
> +static void cleanup_path_device(struct path_device *dev)
> +{
> +        if (dev == NULL)
> +            return;
> +
> +        free(dev->path);
> +
> +}
> +
> +static void cleanup_unixsock_device(struct unixsock_device *dev)
> +{
> +        if (dev == NULL)
> +            return;
> +
> +        free(dev->path);
> +        free(dev->mode);
> +
> +}
> +
> +static void cleanup_tcp_device(struct tcp_device *dev)
> +{
> +        if (dev == NULL)
> +            return;
> +
> +        free(dev->mode);
> +        free(dev->protocol);
> +        free(dev->host);
> +        free(dev->service);
> +
> +}
> +
> +static void cleanup_udp_device(struct udp_device *dev)
> +{
> +        if (dev == NULL)
> +            return;
> +
> +        free(dev->bind_host);
> +        free(dev->bind_service);
> +        free(dev->connect_host);
> +        free(dev->connect_service);
> +};
> +
> +static void cleanup_console_device(struct console_device *dev)
> +{
> +        if (dev == NULL)
> +                return;
> +
> +        switch (dev->source_type)
> +        {
> +        case CIM_CHARDEV_SOURCE_TYPE_PTY:
> +                cleanup_path_device(&dev->source_dev.pty);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_DEV:
> +                cleanup_path_device(&dev->source_dev.dev);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_FILE:
> +                cleanup_path_device(&dev->source_dev.file);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_PIPE:
> +                cleanup_path_device(&dev->source_dev.pipe);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK:
> +                cleanup_unixsock_device(&dev->source_dev.unixsock);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_UDP:
> +                cleanup_udp_device(&dev->source_dev.udp);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_TCP:
> +                cleanup_tcp_device(&dev->source_dev.tcp);
> +                break;
> +        default:
> +                /* Nothing to do for :
> +                   CIM_CHARDEV_SOURCE_TYPE_STDIO
> +                   CIM_CHARDEV_SOURCE_TYPE_NULL
> +                   CIM_CHARDEV_SOURCE_TYPE_VC
> +                   CIM_CHARDEV_SOURCE_TYPE_SPICEVMC
> +                */
> +                break;
> +        }
> +
> +        dev->source_type = 0;
> +        free(dev->target_type);
> +        memset(&dev->source_dev, 0, sizeof(dev->source_dev));
> +};
> +
> +static void console_device_dup(struct console_device *t,
> +                               struct console_device *s)
> +{
> +        cleanup_console_device(t);
> +
> +        t->source_type = s->source_type;
> +        DUP_FIELD(t, s, target_type);
> +
> +        switch (s->source_type)
> +        {
> +        case CIM_CHARDEV_SOURCE_TYPE_PTY:
> +                DUP_FIELD(t, s, source_dev.pty.path);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_DEV:
> +                DUP_FIELD(t, s, source_dev.dev.path);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_FILE:
> +                DUP_FIELD(t, s, source_dev.file.path);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_PIPE:
> +                DUP_FIELD(t, s, source_dev.pipe.path);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK:
> +                DUP_FIELD(t, s, source_dev.unixsock.path);
> +                DUP_FIELD(t, s, source_dev.unixsock.mode);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_UDP:
> +                DUP_FIELD(t, s, source_dev.udp.bind_host);
> +                DUP_FIELD(t, s, source_dev.udp.bind_service);
> +                DUP_FIELD(t, s, source_dev.udp.connect_host);
> +                DUP_FIELD(t, s, source_dev.udp.connect_service);
> +                break;
> +        case CIM_CHARDEV_SOURCE_TYPE_TCP:
> +                DUP_FIELD(t, s, source_dev.tcp.mode);
> +                DUP_FIELD(t, s, source_dev.tcp.protocol);
> +                DUP_FIELD(t, s, source_dev.tcp.host);
> +                DUP_FIELD(t, s, source_dev.tcp.service);
> +                break;
> +        default:
> +                /* Nothing to do for :
> +                   CIM_CHARDEV_SOURCE_TYPE_STDIO
> +                   CIM_CHARDEV_SOURCE_TYPE_NULL
> +                   CIM_CHARDEV_SOURCE_TYPE_VC
> +                   CIM_CHARDEV_SOURCE_TYPE_SPICEVMC
> +                */
> +                break;
> +        }
> +}
> +
>  static void cleanup_input_device(struct input_device *dev)
>  {
>          if (dev == NULL)
> @@ -157,6 +301,8 @@ void cleanup_virt_device(struct virt_device *dev)
>                  cleanup_graphics_device(&dev->dev.graphics);
>          else if (dev->type == CIM_RES_TYPE_INPUT)
>                  cleanup_input_device(&dev->dev.input);
> +        else if (dev->type == CIM_RES_TYPE_CONSOLE)
> +                cleanup_console_device(&dev->dev.console);
>  
>          free(dev->id);
>  
> @@ -613,6 +759,140 @@ static char *get_attr_value_default(xmlNode *node, char *attrname,
>          return ret;
>  }
>  
> +static int parse_console_device(xmlNode *node, struct virt_device **vdevs)
> +{
> +        struct virt_device *vdev = NULL;
> +        struct console_device *cdev = NULL;
> +        char *source_type_str = NULL;
> +        char *target_port_ID = NULL;
> +        char *udp_source_mode = NULL;
> +
> +        xmlNode *child = NULL;
> +
> +        vdev = calloc(1, sizeof(*vdev));
> +        if (vdev == NULL)
> +                goto err;
> +
> +        cdev = &(vdev->dev.console);
> +
> +        source_type_str = get_attr_value(node, "type");
> +        if (source_type_str == NULL)
> +                goto err;
> +        CU_DEBUG("console device type = %s", source_type_str);
> +
> +        cdev->source_type = chardev_source_type_StrToID(source_type_str);
> +        if (cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_UNKNOWN)
> +                goto err;
> +
> +        CU_DEBUG("console device type ID = %d", cdev->source_type);
> +        free(source_type_str);

This is free()'d again in err:, so we get a Coverity complaint about a
double free. You need a "source_type_str = NULL;" here.

> +
> +        for (child = node->children; child != NULL; child = child->next) {
> +                if (XSTREQ(child->name, "target")) {
> +                        cdev->target_type = get_attr_value(child, "type");
> +                        CU_DEBUG("Console device target type = '%s'",
> +                                 cdev->target_type);

If get_attr_value() returns NULL in cdev->target_type, then your
CU_DEBUG() isn't going to be happy.

> +                        target_port_ID = get_attr_value(child, "port");
> +                        if (target_port_ID == NULL)
> +                                goto err;
> +                }
> +
> +                if (XSTREQ(child->name, "source")) {
> +                        switch (cdev->source_type)
> +                        {
> +                        case CIM_CHARDEV_SOURCE_TYPE_PTY:
> +                                cdev->source_dev.pty.path =
> +                                        get_attr_value(child, "path");
> +                                break;
> +                        case CIM_CHARDEV_SOURCE_TYPE_DEV:
> +                                cdev->source_dev.dev.path =
> +                                        get_attr_value(child, "path");
> +                                break;
> +                        case CIM_CHARDEV_SOURCE_TYPE_FILE:
> +                                cdev->source_dev.file.path =
> +                                        get_attr_value(child, "path");
> +                                break;
> +                        case CIM_CHARDEV_SOURCE_TYPE_PIPE:
> +                                cdev->source_dev.pipe.path =
> +                                        get_attr_value(child, "path");
> +                                break;
> +                        case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK:
> +                                cdev->source_dev.unixsock.mode =
> +                                        get_attr_value(child, "mode");
> +                                cdev->source_dev.unixsock.path =
> +                                        get_attr_value(child, "path");
> +                                break;
> +                        case CIM_CHARDEV_SOURCE_TYPE_UDP:
> +                                udp_source_mode = get_attr_value(child, "mode");
> +                                if (udp_source_mode == NULL)
> +                                        goto err;
> +                                if (STREQC(udp_source_mode, "bind")) {
> +                                        cdev->source_dev.udp.bind_host =
> +                                                get_attr_value(child, "host");
> +                                        cdev->source_dev.udp.bind_service =
> +                                                get_attr_value(child, "service");
> +                                }
> +                                else if (STREQC(udp_source_mode, "connect")) {
> +                                        cdev->source_dev.udp.connect_host =
> +                                                get_attr_value(child, "host");
> +                                        cdev->source_dev.udp.connect_service =
> +                                                get_attr_value(child, "service");
> +                                }
> +                                else {
> +                                        CU_DEBUG("unknown udp mode: %s",
> +                                                 udp_source_mode);
> +                                        goto err;
> +                                }
> +                                free(udp_source_mode);


This is free()'d again in err:, so we get a Coverity complaint about a
double free.  You'll need a udp_source_mode = NULL; here.

> +                                break;
> +                        case CIM_CHARDEV_SOURCE_TYPE_TCP:
> +                                cdev->source_dev.tcp.mode =
> +                                        get_attr_value(child, "mode");
> +                                cdev->source_dev.tcp.host =
> +                                        get_attr_value(child, "host");
> +                                cdev->source_dev.tcp.service =
> +                                        get_attr_value(child, "service");
> +                                break;
> +
> +                        default:
> +                                /* Nothing to do for :
> +                                   CIM_CHARDEV_SOURCE_TYPE_STDIO
> +                                   CIM_CHARDEV_SOURCE_TYPE_NULL
> +                                   CIM_CHARDEV_SOURCE_TYPE_VC
> +                                   CIM_CHARDEV_SOURCE_TYPE_SPICEVMC
> +                                */
> +                                break;
> +                        }
> +                }

Not a whole lot of NULL error checking in any of the get_attr_value()
calls, but that seems to be par for the course in the libvirt-cim code.

The rest seemed fine to me.  I can squash in the above listed changes
before pushing unless you really want to make a v2.

John

> +                if ((cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_TCP)
> +                     && XSTREQ(child->name, "protocol")) {
> +                        cdev->source_dev.tcp.protocol =
> +                                get_attr_value(child, "type");
> +                }
> +        }
> +
> +        vdev->type = CIM_RES_TYPE_CONSOLE;
> +
> +        if (-1 == asprintf(&vdev->id, "charconsole:%s", target_port_ID)) {
> +                CU_DEBUG("Failed to create charconsole id string");
> +                goto err;
> +        }
> +
> +        *vdevs = vdev;
> +        free(target_port_ID);
> +
> +        return 1;
> +
> + err:
> +        free(source_type_str);
> +        free(target_port_ID);
> +        free(udp_source_mode);
> +        cleanup_console_device(cdev);
> +        free(vdev);
> +
> +        return 0;
> +}
> +
>  static int parse_graphics_device(xmlNode *node, struct virt_device **vdevs)
>  {
>          struct virt_device *vdev = NULL;
> @@ -664,8 +944,20 @@ static int parse_graphics_device(xmlNode *node, struct virt_device **vdevs)
>                          child = child->next) {
>                          if (XSTREQ(child->name, "source")) 
>                                  gdev->dev.vnc.host = get_attr_value(child, "path");
> -                        else if (XSTREQ(child->name, "target"))
> -                                gdev->dev.vnc.port = get_attr_value(child, "port");
> +                        else if (XSTREQ(child->name, "target")) {
> +                                gdev->dev.vnc.port =
> +                                        get_attr_value(child, "port");
> +                                /* The graphics pty console can only be a
> +                                   virtio console. If 'type' is not set in the
> +                                   xml, the default of libvirt is virtio.*/
> +                                char *t_type = get_attr_value(child, "type");
> +                                if (t_type != NULL && !STREQC(t_type, "virtio")) {
> +                                        CU_DEBUG("Not a pty-virtio graphics console");
> +                                        free(t_type);
> +                                        goto err;
> +                                }
> +                                free(t_type);
> +                        }
>                  }
>          }
>          else {
> @@ -841,6 +1133,11 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type)
>                  func = &parse_graphics_device;
>                  break;
>  
> +        case CIM_RES_TYPE_CONSOLE:
> +                xpathstr = CONSOLE_XPATH;
> +                func = &parse_console_device;
> +                break;
> +
>          case CIM_RES_TYPE_INPUT:
>                  xpathstr = INPUT_XPATH;
>                  func = &parse_input_device;
> @@ -876,11 +1173,6 @@ static int parse_devices(const char *xml, struct virt_device **_list, int type)
>          return count;
>  }
>  
> -#define DUP_FIELD(d, s, f) do {                         \
> -                if ((s)->f != NULL)                     \
> -                        (d)->f = strdup((s)->f);        \
> -        } while (0);
> -
>  struct virt_device *virt_device_dup(struct virt_device *_dev)
>  {
>          struct virt_device *dev;
> @@ -939,8 +1231,10 @@ struct virt_device *virt_device_dup(struct virt_device *_dev)
>          } else if (dev->type == CIM_RES_TYPE_INPUT) {
>                  DUP_FIELD(dev, _dev, dev.input.type);
>                  DUP_FIELD(dev, _dev, dev.input.bus);
> +        } else if (dev->type == CIM_RES_TYPE_CONSOLE) {
> +                console_device_dup(&dev->dev.console,
> +                                   &_dev->dev.console);
>          }
> -
>          return dev;
>  }
>  
> @@ -1299,6 +1593,9 @@ int get_dominfo_from_xml(const char *xml, struct domain **dominfo)
>          (*dominfo)->dev_graphics_ct = parse_devices(xml, 
>                                                      &(*dominfo)->dev_graphics, 
>                                                      CIM_RES_TYPE_GRAPHICS);
> +        (*dominfo)->dev_console_ct = parse_devices(xml,
> +                                                   &(*dominfo)->dev_console,
> +                                                   CIM_RES_TYPE_CONSOLE);
>          (*dominfo)->dev_input_ct = parse_devices(xml, 
>                                                   &(*dominfo)->dev_input, 
>                                                   CIM_RES_TYPE_INPUT);
> @@ -1396,6 +1693,7 @@ void cleanup_dominfo(struct domain **dominfo)
>          cleanup_virt_devices(&dom->dev_vcpu, dom->dev_vcpu_ct);
>          cleanup_virt_devices(&dom->dev_graphics, dom->dev_graphics_ct);
>          cleanup_virt_devices(&dom->dev_input, dom->dev_input_ct);
> +        cleanup_virt_devices(&dom->dev_console, dom->dev_console_ct);
>  
>          free(dom);
>  
> diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h
> index 14e49b8..2803d6a 100644
> --- a/libxkutil/device_parsing.h
> +++ b/libxkutil/device_parsing.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright IBM Corp. 2007
> + * Copyright IBM Corp. 2007, 2013
>   *
>   * Authors:
>   *  Dan Smith <danms at us.ibm.com>
> @@ -111,6 +111,43 @@ struct graphics_device {
>          } dev;
>  };
>  
> +struct path_device {
> +        char *path;
> +};
> +
> +struct unixsock_device {
> +        char *path;
> +        char *mode;
> +};
> +
> +struct tcp_device {
> +        char *mode;
> +        char *protocol;
> +        char *host;
> +        char *service;
> +};
> +
> +struct udp_device {
> +        char *bind_host;
> +        char *bind_service;
> +        char *connect_host;
> +        char *connect_service;
> +};
> +
> +struct console_device {
> +        uint16_t source_type;
> +        union {
> +                struct path_device file;
> +                struct path_device pty;
> +                struct path_device dev;
> +                struct path_device pipe;
> +                struct unixsock_device unixsock;
> +                struct tcp_device  tcp;
> +                struct udp_device  udp;
> +        }  source_dev;
> +        char *target_type;
> +};
> +
>  struct input_device {
>          char *type;
>          char *bus;
> @@ -125,6 +162,7 @@ struct virt_device {
>                  struct vcpu_device vcpu;
>                  struct emu_device emu;
>                  struct graphics_device graphics;
> +                struct console_device console;
>                  struct input_device input;
>          } dev;
>          char *id;
> @@ -182,6 +220,9 @@ struct domain {
>          struct virt_device *dev_graphics;
>          int dev_graphics_ct;
>  
> +        struct virt_device *dev_console;
> +        int dev_console_ct;
> +
>          struct virt_device *dev_emu;
>  
>          struct virt_device *dev_input;
> diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
> index 2ca2341..45bfb04 100644
> --- a/libxkutil/xmlgen.c
> +++ b/libxkutil/xmlgen.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright IBM Corp. 2007
> + * Copyright IBM Corp. 2007, 2013
>   *
>   * Authors:
>   *  Dan Smith <danms at us.ibm.com>
> @@ -42,6 +42,189 @@ typedef const char *(*devfn_t)(xmlNodePtr node, struct domain *dominfo);
>  typedef const char *(*poolfn_t)(xmlNodePtr node, struct virt_pool *pool);
>  typedef const char *(*resfn_t)(xmlNodePtr node, struct virt_pool_res *res);
>  
> +static int _count_graphics_console_definitions(struct domain *dominfo)
> +{
> +        int i;
> +        int num = 0;
> +
> +        for (i = 0; i < dominfo->dev_graphics_ct; i++) {
> +                struct virt_device *_dev = &dominfo->dev_graphics[i];
> +                if (_dev->type == CIM_RES_TYPE_UNKNOWN)
> +                        continue;
> +
> +                struct graphics_device *dev = &_dev->dev.graphics;
> +
> +                if (STREQC(dev->type, "console")) {
> +                        num++;
> +                }
> +        }
> +        CU_DEBUG("Found %d console defintions in graphics devices.",num);
> +        return num;
> +
> +}
> +
> +static const char *console_xml(xmlNodePtr root, struct domain *dominfo)
> +{
> +        int i;
> +        xmlNodePtr console;
> +        xmlNodePtr tmp;
> +        int num_graphics_consol_def = 0;
> +        int num_suppressed_console_def = 0;
> +
> +        num_graphics_consol_def = _count_graphics_console_definitions(dominfo);
> +
> +        for (i = 0; i < dominfo->dev_console_ct; i++) {
> +                struct virt_device *_dev = &dominfo->dev_console[i];
> +                if (_dev->type == CIM_RES_TYPE_UNKNOWN)
> +                        continue;
> +
> +                struct console_device *cdev = &_dev->dev.console;
> +
> +                /* Due to backward compatibility, the graphics device handling
> +                   is still parsing consoles:
> +                   source = pty, target = virtio (which is the default target)
> +                   But the console device handling processes these kind of
> +                   consoles too. This would lead to a duplication of these
> +                   default consoles in the domain xml definition.
> +                   This code prevents the console handling of writing xml for
> +                   duplicate pty/virtio consoles which are written by the
> +                   graphics device handling. */
> +                if (cdev->source_type == CIM_CHARDEV_SOURCE_TYPE_PTY &&
> +                    (cdev->target_type == NULL ||
> +                     STREQC(cdev->target_type, "virtio"))) {
> +                        if (num_suppressed_console_def <
> +                            num_graphics_consol_def) {
> +                                num_suppressed_console_def++;
> +                                continue;
> +                        }
> +                }
> +
> +                console = xmlNewChild(root, NULL, BAD_CAST "console", NULL);
> +                if (console == NULL)
> +                        return XML_ERROR;
> +
> +                xmlNewProp(console, BAD_CAST "type",
> +                           BAD_CAST
> +                           chardev_source_type_IDToStr(cdev->source_type));
> +
> +                switch (cdev->source_type) {
> +                case CIM_CHARDEV_SOURCE_TYPE_PTY:
> +                        /* The path property is not mandatory */
> +                        if (cdev->source_dev.pty.path) {
> +                                tmp = xmlNewChild(console, NULL,
> +                                                  BAD_CAST "source", NULL);
> +                                if (tmp == NULL)
> +                                        return XML_ERROR;
> +                                xmlNewProp(tmp, BAD_CAST "path",
> +                                           BAD_CAST cdev->source_dev.pty.path);
> +                        }
> +                        break;
> +                case CIM_CHARDEV_SOURCE_TYPE_DEV:
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "path",
> +                                   BAD_CAST cdev->source_dev.dev.path);
> +                        break;
> +                case CIM_CHARDEV_SOURCE_TYPE_FILE:
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "path",
> +                                   BAD_CAST cdev->source_dev.file.path);
> +                        break;
> +                case CIM_CHARDEV_SOURCE_TYPE_PIPE:
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "path",
> +                                   BAD_CAST cdev->source_dev.pipe.path);
> +                        break;
> +                case CIM_CHARDEV_SOURCE_TYPE_UNIXSOCK:
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "mode",
> +                                   BAD_CAST cdev->source_dev.unixsock.mode);
> +                        xmlNewProp(tmp, BAD_CAST "path",
> +                                   BAD_CAST cdev->source_dev.unixsock.path);
> +                        break;
> +                case CIM_CHARDEV_SOURCE_TYPE_UDP:
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "mode", BAD_CAST "bind");
> +                        xmlNewProp(tmp, BAD_CAST "host",
> +                                   BAD_CAST cdev->source_dev.udp.bind_host);
> +                        /* The service property is not mandatory */
> +                        if (cdev->source_dev.udp.bind_service)
> +                                xmlNewProp(tmp, BAD_CAST "service",
> +                                           BAD_CAST
> +                                           cdev->source_dev.udp.bind_service);
> +
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "mode", BAD_CAST "connect");
> +                        xmlNewProp(tmp, BAD_CAST "host",
> +                                   BAD_CAST cdev->source_dev.udp.connect_host);
> +                        /* The service property is not mandatory */
> +                        if (cdev->source_dev.udp.connect_service)
> +                                xmlNewProp(tmp, BAD_CAST "service",
> +                                           BAD_CAST
> +                                           cdev->source_dev.udp.connect_service);
> +
> +                        break;
> +                case CIM_CHARDEV_SOURCE_TYPE_TCP:
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "source", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "mode",
> +                                   BAD_CAST cdev->source_dev.tcp.mode);
> +                        xmlNewProp(tmp, BAD_CAST "host",
> +                                   BAD_CAST cdev->source_dev.tcp.host);
> +                        if (cdev->source_dev.tcp.service)
> +                                xmlNewProp(tmp, BAD_CAST "service",
> +                                           BAD_CAST
> +                                           cdev->source_dev.tcp.service);
> +                        if (cdev->source_dev.tcp.protocol) {
> +                                tmp = xmlNewChild(console, NULL,
> +                                                  BAD_CAST "protocol", NULL);
> +                                if (tmp == NULL)
> +                                        return XML_ERROR;
> +                                xmlNewProp(tmp, BAD_CAST "type",
> +                                           BAD_CAST cdev->source_dev.tcp.protocol);
> +                        }
> +                        break;
> +                default:
> +                        /* Nothing to do for :
> +                           CIM_CHARDEV_SOURCE_TYPE_STDIO
> +                           CIM_CHARDEV_SOURCE_TYPE_NULL
> +                           CIM_CHARDEV_SOURCE_TYPE_VC
> +                           CIM_CHARDEV_SOURCE_TYPE_SPICEVMC
> +                        */
> +                        break;
> +                }
> +
> +                if (cdev->target_type) {
> +                        tmp = xmlNewChild(console, NULL,
> +                                          BAD_CAST "target", NULL);
> +                        if (tmp == NULL)
> +                                return XML_ERROR;
> +                        xmlNewProp(tmp, BAD_CAST "type",
> +                                   BAD_CAST cdev->target_type);
> +                }
> +        }
> +        return NULL;
> +}
> +
>  static char *disk_block_xml(xmlNodePtr root, struct disk_device *dev)
>  {
>          xmlNodePtr disk;
> @@ -977,6 +1160,11 @@ char *device_to_xml(struct virt_device *_dev)
>                  dominfo->dev_graphics_ct = 1;
>                  dominfo->dev_graphics = dev;
>                  break;
> +        case CIM_RES_TYPE_CONSOLE:
> +                func = console_xml;
> +                dominfo->dev_console_ct = 1;
> +                dominfo->dev_console = dev;
> +                break;
>          case CIM_RES_TYPE_INPUT:
>                  func = input_xml;
>                  dominfo->dev_input_ct = 1;
> @@ -1017,6 +1205,7 @@ char *system_to_xml(struct domain *dominfo)
>                  &disk_xml,
>                  &net_xml,
>                  &input_xml,
> +                &console_xml,
>                  &graphics_xml,
>                  &emu_xml,
>                  NULL
> diff --git a/src/svpc_types.h b/src/svpc_types.h
> index 2e4d73f..0f46a86 100644
> --- a/src/svpc_types.h
> +++ b/src/svpc_types.h
> @@ -25,6 +25,7 @@
>  #define CIM_OPERATIONAL_STATUS 2
>  
>  #define CIM_RES_TYPE_ALL        0
> +#define CIM_RES_TYPE_OTHER      1
>  #define CIM_RES_TYPE_PROC       3
>  #define CIM_RES_TYPE_MEM        4
>  #define CIM_RES_TYPE_NET        10
> @@ -34,8 +35,9 @@
>  #define CIM_RES_TYPE_INPUT      13 
>  #define CIM_RES_TYPE_UNKNOWN    1000
>  #define CIM_RES_TYPE_IMAGE      32768 
> +#define CIM_RES_TYPE_CONSOLE    32769
>  
> -#define CIM_RES_TYPE_COUNT 6
> +#define CIM_RES_TYPE_COUNT 7
>  const static int cim_res_types[CIM_RES_TYPE_COUNT] = 
>    {CIM_RES_TYPE_NET,
>     CIM_RES_TYPE_DISK,
> @@ -43,6 +45,7 @@ const static int cim_res_types[CIM_RES_TYPE_COUNT] =
>     CIM_RES_TYPE_PROC,
>     CIM_RES_TYPE_GRAPHICS,
>     CIM_RES_TYPE_INPUT,
> +   CIM_RES_TYPE_CONSOLE,
>    };
>  
>  #define CIM_VSSD_RECOVERY_NONE       2
> 




More information about the Libvirt-cim mailing list