All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
@ 2017-02-09  5:23 Ashish Mittal
  2017-02-09  5:23 ` [Qemu-devel] [PATCH v8 2/2] block/vxhs.c: Add qemu-iotests for new block device type "vxhs" Ashish Mittal
  2017-02-09  6:29 ` [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Jeff Cody
  0 siblings, 2 replies; 56+ messages in thread
From: Ashish Mittal @ 2017-02-09  5:23 UTC (permalink / raw)
  To: qemu-devel, pbonzini, kwolf, armbru, berrange, jcody, famz,
	ashish.mittal, stefanha, jferlan, Buddhi.Madhav, Suraj.Singh,
	Nitin.Jerath, peter.maydell
  Cc: Ketan.Nilangekar, Abhijit.Dey

From: Ashish Mittal <ashish.mittal@veritas.com>

Source code for the qnio library that this code loads can be downloaded from:
https://github.com/VeritasHyperScale/libqnio.git

Sample command line using JSON syntax:
./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
-k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
-msg timestamp=on
'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
"server":{"host":"172.172.17.4","port":"9999"}}'

Sample command line using URI syntax:
qemu-img convert -f raw -O raw -n
/var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0

Signed-off-by: Ashish Mittal <ashish.mittal@veritas.com>
---
TODO:
(1) valgrind report to follow soon.

v8 changelog:
(1) Security implementation for libqnio present in branch 'securify'.
    Please use 'securify' branch for building libqnio and testing
    with this patch.
(2) Renamed libqnio to libvxhs.
(3) Pass instance ID to libvxhs for SSL authentication.

v7 changelog:
(1) IO failover code has moved out to the libqnio library.
(2) Fixes for issues reported by Stefan on v6.
(3) Incorporated the QEMUBH patch provided by Stefan.
    This is a replacement for the pipe mechanism used earlier.
(4) Fixes to the buffer overflows reported in libqnio.
(5) Input validations in vxhs.c to prevent any buffer overflows for 
    arguments passed to libqnio.

v6 changelog:
(1) Added qemu-iotests for VxHS as a new patch in the series.
(2) Replaced release version from 2.8 to 2.9 in block-core.json.

v5 changelog:
(1) Incorporated v4 review comments.

v4 changelog:
(1) Incorporated v3 review comments on QAPI changes.
(2) Added refcounting for device open/close.
    Free library resources on last device close.

v3 changelog:
(1) Added QAPI schema for the VxHS driver.

v2 changelog:
(1) Changes done in response to v1 comments.

 block/Makefile.objs  |   2 +
 block/trace-events   |  16 ++
 block/vxhs.c         | 499 +++++++++++++++++++++++++++++++++++++++++++++++++++
 configure            |  41 +++++
 qapi/block-core.json |  20 ++-
 5 files changed, 576 insertions(+), 2 deletions(-)
 create mode 100644 block/vxhs.c

diff --git a/block/Makefile.objs b/block/Makefile.objs
index c6bd14e..75675b4 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -19,6 +19,7 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
 block-obj-$(CONFIG_CURL) += curl.o
 block-obj-$(CONFIG_RBD) += rbd.o
 block-obj-$(CONFIG_GLUSTERFS) += gluster.o
+block-obj-$(CONFIG_VXHS) += vxhs.o
 block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
 block-obj-$(CONFIG_LIBSSH2) += ssh.o
 block-obj-y += accounting.o dirty-bitmap.o
@@ -39,6 +40,7 @@ rbd.o-cflags       := $(RBD_CFLAGS)
 rbd.o-libs         := $(RBD_LIBS)
 gluster.o-cflags   := $(GLUSTERFS_CFLAGS)
 gluster.o-libs     := $(GLUSTERFS_LIBS)
+vxhs.o-libs        := $(VXHS_LIBS)
 ssh.o-cflags       := $(LIBSSH2_CFLAGS)
 ssh.o-libs         := $(LIBSSH2_LIBS)
 archipelago.o-libs := $(ARCHIPELAGO_LIBS)
diff --git a/block/trace-events b/block/trace-events
index 0bc5c0a..d5eca93 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -110,3 +110,19 @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
 qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
 qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
 qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+
+# block/vxhs.c
+vxhs_iio_callback(int error) "ctx is NULL: error %d"
+vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
+vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
+vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
+vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu offset = %lu ACB = %p. Error = %d, errno = %d"
+vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
+vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %lu"
+vxhs_qnio_iio_open(const char *ip) "Failed to connect to storage agent on host-ip %s"
+vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld"
+vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
+vxhs_qemu_init_vdisk(const char *vdisk_id) "vdisk-id from json %s"
+vxhs_parse_uri_hostinfo(int num, char *host, int port) "Host %d: IP %s, Port %d"
+vxhs_qemu_init(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
+vxhs_close(char *vdisk_guid) "Closing vdisk %s"
diff --git a/block/vxhs.c b/block/vxhs.c
new file mode 100644
index 0000000..f1b5f1c
--- /dev/null
+++ b/block/vxhs.c
@@ -0,0 +1,499 @@
+/*
+ * QEMU Block driver for Veritas HyperScale (VxHS)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include <qnio/qnio_api.h>
+#include <sys/param.h>
+#include "block/block_int.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "trace.h"
+#include "qemu/uri.h"
+#include "qapi/error.h"
+#include "qemu/uuid.h"
+
+#define VXHS_OPT_FILENAME           "filename"
+#define VXHS_OPT_VDISK_ID           "vdisk-id"
+#define VXHS_OPT_SERVER             "server"
+#define VXHS_OPT_HOST               "host"
+#define VXHS_OPT_PORT               "port"
+#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
+
+QemuUUID qemu_uuid __attribute__ ((weak));
+
+static int lib_init_failed;
+
+typedef enum {
+    VDISK_AIO_READ,
+    VDISK_AIO_WRITE,
+} VDISKAIOCmd;
+
+/*
+ * HyperScale AIO callbacks structure
+ */
+typedef struct VXHSAIOCB {
+    BlockAIOCB common;
+    int err;
+    QEMUIOVector *qiov;
+} VXHSAIOCB;
+
+typedef struct VXHSvDiskHostsInfo {
+    void *dev_handle; /* Device handle */
+    char *host; /* Host name or IP */
+    int port; /* Host's port number */
+} VXHSvDiskHostsInfo;
+
+/*
+ * Structure per vDisk maintained for state
+ */
+typedef struct BDRVVXHSState {
+    VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
+    char *vdisk_guid;
+} BDRVVXHSState;
+
+static void vxhs_complete_aio_bh(void *opaque)
+{
+    VXHSAIOCB *acb = opaque;
+    BlockCompletionFunc *cb = acb->common.cb;
+    void *cb_opaque = acb->common.opaque;
+    int ret = 0;
+
+    if (acb->err != 0) {
+        trace_vxhs_complete_aio(acb, acb->err);
+        ret = (-EIO);
+    }
+
+    qemu_aio_unref(acb);
+    cb(cb_opaque, ret);
+}
+
+/*
+ * Called from a libqnio thread
+ */
+static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
+{
+    VXHSAIOCB *acb = NULL;
+
+    switch (opcode) {
+    case IRP_READ_REQUEST:
+    case IRP_WRITE_REQUEST:
+
+        /*
+         * ctx is VXHSAIOCB*
+         * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
+         */
+        if (ctx) {
+            acb = ctx;
+        } else {
+            trace_vxhs_iio_callback(error);
+            goto out;
+        }
+
+        if (error) {
+            if (!acb->err) {
+                acb->err = error;
+            }
+            trace_vxhs_iio_callback(error);
+        }
+
+        aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
+                                vxhs_complete_aio_bh, acb);
+        break;
+
+    default:
+        if (error == QNIOERROR_HUP) {
+            /*
+             * Channel failed, spontaneous notification,
+             * not in response to I/O
+             */
+            trace_vxhs_iio_callback_chnfail(error, errno);
+        } else {
+            trace_vxhs_iio_callback_unknwn(opcode, error);
+        }
+        break;
+    }
+out:
+    return;
+}
+
+static QemuOptsList runtime_opts = {
+    .name = "vxhs",
+    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
+    .desc = {
+        {
+            .name = VXHS_OPT_FILENAME,
+            .type = QEMU_OPT_STRING,
+            .help = "URI to the Veritas HyperScale image",
+        },
+        {
+            .name = VXHS_OPT_VDISK_ID,
+            .type = QEMU_OPT_STRING,
+            .help = "UUID of the VxHS vdisk",
+        },
+        { /* end of list */ }
+    },
+};
+
+static QemuOptsList runtime_tcp_opts = {
+    .name = "vxhs_tcp",
+    .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
+    .desc = {
+        {
+            .name = VXHS_OPT_HOST,
+            .type = QEMU_OPT_STRING,
+            .help = "host address (ipv4 addresses)",
+        },
+        {
+            .name = VXHS_OPT_PORT,
+            .type = QEMU_OPT_NUMBER,
+            .help = "port number on which VxHSD is listening (default 9999)",
+            .def_value_str = "9999"
+        },
+        { /* end of list */ }
+    },
+};
+
+/*
+ * Parse the incoming URI and populate *options with the host information.
+ * URI syntax has the limitation of supporting only one host info.
+ * To pass multiple host information, use the JSON syntax.
+ */
+static int vxhs_parse_uri(const char *filename, QDict *options)
+{
+    URI *uri = NULL;
+    char *hoststr, *portstr;
+    char *port;
+    int ret = 0;
+
+    trace_vxhs_parse_uri_filename(filename);
+    uri = uri_parse(filename);
+    if (!uri || !uri->server || !uri->path) {
+        uri_free(uri);
+        return -EINVAL;
+    }
+
+    hoststr = g_strdup(VXHS_OPT_SERVER".host");
+    qdict_put(options, hoststr, qstring_from_str(uri->server));
+    g_free(hoststr);
+
+    portstr = g_strdup(VXHS_OPT_SERVER".port");
+    if (uri->port) {
+        port = g_strdup_printf("%d", uri->port);
+        qdict_put(options, portstr, qstring_from_str(port));
+        g_free(port);
+    }
+    g_free(portstr);
+
+    if (strstr(uri->path, "vxhs") == NULL) {
+        qdict_put(options, "vdisk-id", qstring_from_str(uri->path));
+    }
+
+    trace_vxhs_parse_uri_hostinfo(1, uri->server, uri->port);
+    uri_free(uri);
+
+    return ret;
+}
+
+static void vxhs_parse_filename(const char *filename, QDict *options,
+                                Error **errp)
+{
+    if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
+        error_setg(errp, "vdisk-id/server and a file name may not be specified "
+                         "at the same time");
+        return;
+    }
+
+    if (strstr(filename, "://")) {
+        int ret = vxhs_parse_uri(filename, options);
+        if (ret < 0) {
+            error_setg(errp, "Invalid URI. URI should be of the form "
+                       "  vxhs://<host_ip>:<port>/<vdisk-id>");
+        }
+    }
+}
+
+static int vxhs_open(BlockDriverState *bs, QDict *options,
+                     int bdrv_flags, Error **errp)
+{
+    BDRVVXHSState *s = bs->opaque;
+    void *dev_handlep = NULL;
+    QDict *backing_options = NULL;
+    QemuOpts *opts, *tcp_opts;
+    char *of_vsa_addr = NULL;
+    Error *local_err = NULL;
+    const char *vdisk_id_opt;
+    const char *server_host_opt;
+    char *str = NULL;
+    int ret = 0;
+
+    if (lib_init_failed) {
+        return -ENODEV;
+    }
+    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
+    qemu_opts_absorb_qdict(opts, options, &local_err);
+    if (local_err) {
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* vdisk-id is the disk UUID */
+    vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
+    if (!vdisk_id_opt) {
+        error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* vdisk-id may contain a leading '/' */
+    if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
+        error_setg(errp, "vdisk-id cannot be more than %d characters",
+                   UUID_FMT_LEN);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    s->vdisk_guid = g_strdup(vdisk_id_opt);
+    trace_vxhs_qemu_init_vdisk(vdisk_id_opt);
+
+    str = g_strdup_printf(VXHS_OPT_SERVER".");
+    qdict_extract_subqdict(options, &backing_options, str);
+
+    /* Create opts info from runtime_tcp_opts list */
+    tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
+    qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
+    if (local_err) {
+        qdict_del(backing_options, str);
+        qemu_opts_del(tcp_opts);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
+    if (!server_host_opt) {
+        error_setg(&local_err, QERR_MISSING_PARAMETER,
+                   VXHS_OPT_SERVER"."VXHS_OPT_HOST);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
+        error_setg(errp, "server.host cannot be more than %d characters",
+                   MAXHOSTNAMELEN);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
+
+    s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
+                                                          VXHS_OPT_PORT),
+                                                          NULL, 0);
+
+    trace_vxhs_qemu_init(s->vdisk_hostinfo.host,
+                         s->vdisk_hostinfo.port);
+
+    qdict_del(backing_options, str);
+    qemu_opts_del(tcp_opts);
+
+    of_vsa_addr = g_strdup_printf("of://%s:%d",
+                                s->vdisk_hostinfo.host,
+                                s->vdisk_hostinfo.port);
+
+    /*
+     * Open qnio channel to storage agent if not opened before.
+     */
+    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0);
+    if (dev_handlep == NULL) {
+        trace_vxhs_qnio_iio_open(of_vsa_addr);
+        ret = -ENODEV;
+        goto out;
+    }
+    s->vdisk_hostinfo.dev_handle = dev_handlep;
+
+out:
+    g_free(str);
+    g_free(of_vsa_addr);
+    QDECREF(backing_options);
+    qemu_opts_del(opts);
+
+    if (ret < 0) {
+        error_propagate(errp, local_err);
+        g_free(s->vdisk_hostinfo.host);
+        g_free(s->vdisk_guid);
+        s->vdisk_guid = NULL;
+        errno = -ret;
+    }
+
+    return ret;
+}
+
+static const AIOCBInfo vxhs_aiocb_info = {
+    .aiocb_size = sizeof(VXHSAIOCB)
+};
+
+/*
+ * This allocates QEMU-VXHS callback for each IO
+ * and is passed to QNIO. When QNIO completes the work,
+ * it will be passed back through the callback.
+ */
+static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
+                               QEMUIOVector *qiov, int nb_sectors,
+                               BlockCompletionFunc *cb, void *opaque,
+                               VDISKAIOCmd iodir)
+{
+    VXHSAIOCB *acb = NULL;
+    BDRVVXHSState *s = bs->opaque;
+    size_t size;
+    uint64_t offset;
+    int iio_flags = 0;
+    int ret = 0;
+    void *dev_handle = s->vdisk_hostinfo.dev_handle;
+
+    offset = sector_num * BDRV_SECTOR_SIZE;
+    size = nb_sectors * BDRV_SECTOR_SIZE;
+    acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
+
+    /*
+     * Initialize VXHSAIOCB.
+     */
+    acb->err = 0;
+    acb->qiov = qiov;
+
+    iio_flags = IIO_FLAG_ASYNC;
+
+    switch (iodir) {
+    case VDISK_AIO_WRITE:
+            ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
+                             offset, (uint64_t)size, iio_flags);
+            break;
+    case VDISK_AIO_READ:
+            ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
+                            offset, (uint64_t)size, iio_flags);
+            break;
+    default:
+            trace_vxhs_aio_rw_invalid(iodir);
+            goto errout;
+    }
+
+    if (ret != 0) {
+        trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
+                                acb, ret, errno);
+        goto errout;
+    }
+    return &acb->common;
+
+errout:
+    qemu_aio_unref(acb);
+    return NULL;
+}
+
+static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
+                                   int64_t sector_num, QEMUIOVector *qiov,
+                                   int nb_sectors,
+                                   BlockCompletionFunc *cb, void *opaque)
+{
+    return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
+                       opaque, VDISK_AIO_READ);
+}
+
+static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
+                                   int64_t sector_num, QEMUIOVector *qiov,
+                                   int nb_sectors,
+                                   BlockCompletionFunc *cb, void *opaque)
+{
+    return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
+                       cb, opaque, VDISK_AIO_WRITE);
+}
+
+static void vxhs_close(BlockDriverState *bs)
+{
+    BDRVVXHSState *s = bs->opaque;
+
+    trace_vxhs_close(s->vdisk_guid);
+
+    g_free(s->vdisk_guid);
+    s->vdisk_guid = NULL;
+
+    /*
+     * Close vDisk device
+     */
+    if (s->vdisk_hostinfo.dev_handle) {
+        iio_close(s->vdisk_hostinfo.dev_handle);
+        s->vdisk_hostinfo.dev_handle = NULL;
+    }
+
+    /*
+     * Free the dynamically allocated host string
+     */
+    g_free(s->vdisk_hostinfo.host);
+    s->vdisk_hostinfo.host = NULL;
+    s->vdisk_hostinfo.port = 0;
+}
+
+static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
+{
+    int64_t vdisk_size = -1;
+    int ret = 0;
+    void *dev_handle = s->vdisk_hostinfo.dev_handle;
+
+    ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
+    if (ret < 0) {
+        trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
+        return -EIO;
+    }
+
+    trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
+    return vdisk_size;
+}
+
+/*
+ * Returns the size of vDisk in bytes. This is required
+ * by QEMU block upper block layer so that it is visible
+ * to guest.
+ */
+static int64_t vxhs_getlength(BlockDriverState *bs)
+{
+    BDRVVXHSState *s = bs->opaque;
+    int64_t vdisk_size;
+
+    vdisk_size = vxhs_get_vdisk_stat(s);
+    if (vdisk_size < 0) {
+        return -EIO;
+    }
+
+    return vdisk_size;
+}
+
+static BlockDriver bdrv_vxhs = {
+    .format_name                  = "vxhs",
+    .protocol_name                = "vxhs",
+    .instance_size                = sizeof(BDRVVXHSState),
+    .bdrv_file_open               = vxhs_open,
+    .bdrv_parse_filename          = vxhs_parse_filename,
+    .bdrv_close                   = vxhs_close,
+    .bdrv_getlength               = vxhs_getlength,
+    .bdrv_aio_readv               = vxhs_aio_readv,
+    .bdrv_aio_writev              = vxhs_aio_writev,
+};
+
+static void bdrv_vxhs_init(void)
+{
+    char out[37];
+
+    if (qemu_uuid_is_null(&qemu_uuid)) {
+        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
+    } else {
+        qemu_uuid_unparse(&qemu_uuid, out);
+        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
+    }
+
+    bdrv_register(&bdrv_vxhs);
+}
+
+block_init(bdrv_vxhs_init);
diff --git a/configure b/configure
index 6325339..c3ccf02 100755
--- a/configure
+++ b/configure
@@ -321,6 +321,7 @@ numa=""
 tcmalloc="no"
 jemalloc="no"
 replication="yes"
+vxhs=""
 
 # parse CC options first
 for opt do
@@ -1170,6 +1171,10 @@ for opt do
   ;;
   --enable-replication) replication="yes"
   ;;
+  --disable-vxhs) vxhs="no"
+  ;;
+  --enable-vxhs) vxhs="yes"
+  ;;
   *)
       echo "ERROR: unknown option $opt"
       echo "Try '$0 --help' for more information"
@@ -1403,6 +1408,7 @@ disabled with --disable-FEATURE, default is enabled if available:
   tcmalloc        tcmalloc support
   jemalloc        jemalloc support
   replication     replication support
+  vxhs            Veritas HyperScale vDisk backend support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -4748,6 +4754,34 @@ if test "$modules" = "yes" && test "$LD_REL_FLAGS" = ""; then
 fi
 
 ##########################################
+# Veritas HyperScale block driver VxHS
+# Check if libvxhs is installed
+
+if test "$vxhs" != "no" ; then
+  cat > $TMPC <<EOF
+#include <stdint.h>
+#include <qnio/qnio_api.h>
+
+#define VXHS_UUID "12345678-1234-1234-1234-123456789012"
+void *vxhs_callback;
+
+int main(void) {
+    iio_init(QNIO_VERSION, vxhs_callback, VXHS_UUID);
+    return 0;
+}
+EOF
+  vxhs_libs="-lvxhs -lssl"
+  if compile_prog "" "$vxhs_libs" ; then
+    vxhs=yes
+  else
+    if test "$vxhs" = "yes" ; then
+      feature_not_found "vxhs block device" "Install libvxhs See github"
+    fi
+    vxhs=no
+  fi
+fi
+
+##########################################
 # End of CC checks
 # After here, no more $cc or $ld runs
 
@@ -5114,6 +5148,7 @@ echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
 echo "replication support $replication"
+echo "VxHS block device $vxhs"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5729,6 +5764,12 @@ if test "$pthread_setname_np" = "yes" ; then
   echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak
 fi
 
+if test "$vxhs" = "yes" ; then
+  echo "CONFIG_VXHS=y" >> $config_host_mak
+  echo "VXHS_CFLAGS=$vxhs_cflags" >> $config_host_mak
+  echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
+fi
+
 if test "$tcg_interpreter" = "yes"; then
   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
 elif test "$ARCH" = "sparc64" ; then
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 932f5bb..f37df56 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2110,6 +2110,7 @@
 # @nfs: Since 2.8
 # @replication: Since 2.8
 # @ssh: Since 2.8
+# @vxhs: Since 2.9
 #
 # Since: 2.0
 ##
@@ -2119,7 +2120,7 @@
             'host_device', 'http', 'https', 'luks', 'nbd', 'nfs', 'null-aio',
             'null-co', 'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw',
             'replication', 'ssh', 'vdi', 'vhdx', 'vmdk', 'vpc',
-            'vvfat' ] }
+            'vvfat','vxhs' ] }
 
 ##
 # @BlockdevOptionsFile:
@@ -2744,6 +2745,20 @@
   'data': { '*offset': 'int', '*size': 'int' } }
 
 ##
+# @BlockdevOptionsVxHS:
+#
+# Driver specific block device options for VxHS
+#
+# @vdisk-id:    UUID of VxHS volume
+# @server:      vxhs server IP, port
+#
+# Since: 2.9
+##
+{ 'struct': 'BlockdevOptionsVxHS',
+  'data': { 'vdisk-id': 'str',
+            'server': 'InetSocketAddress' } }
+
+##
 # @BlockdevOptions:
 #
 # Options for creating a block device.  Many options are available for all
@@ -2806,7 +2821,8 @@
       'vhdx':       'BlockdevOptionsGenericFormat',
       'vmdk':       'BlockdevOptionsGenericCOWFormat',
       'vpc':        'BlockdevOptionsGenericFormat',
-      'vvfat':      'BlockdevOptionsVVFAT'
+      'vvfat':      'BlockdevOptionsVVFAT',
+      'vxhs':       'BlockdevOptionsVxHS'
   } }
 
 ##
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* [Qemu-devel] [PATCH v8 2/2] block/vxhs.c: Add qemu-iotests for new block device type "vxhs"
  2017-02-09  5:23 [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Ashish Mittal
@ 2017-02-09  5:23 ` Ashish Mittal
  2017-02-09  6:29 ` [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Jeff Cody
  1 sibling, 0 replies; 56+ messages in thread
From: Ashish Mittal @ 2017-02-09  5:23 UTC (permalink / raw)
  To: qemu-devel, pbonzini, kwolf, armbru, berrange, jcody, famz,
	ashish.mittal, stefanha, jferlan, Buddhi.Madhav, Suraj.Singh,
	Nitin.Jerath, peter.maydell
  Cc: Ketan.Nilangekar, Abhijit.Dey

From: Ashish Mittal <ashish.mittal@veritas.com>

These changes use a vxhs test server that is a part of the following
repository:
https://github.com/VeritasHyperScale/libqnio.git

Signed-off-by: Ashish Mittal <ashish.mittal@veritas.com>
---
v8/v7 changelog:
(1) No changes.

v6 changelog:
(1) Added iotests for VxHS block device.

 tests/qemu-iotests/common        |  6 ++++++
 tests/qemu-iotests/common.config | 13 +++++++++++++
 tests/qemu-iotests/common.filter |  1 +
 tests/qemu-iotests/common.rc     | 19 +++++++++++++++++++
 4 files changed, 39 insertions(+)

diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
index b6274be..318a81d 100644
--- a/tests/qemu-iotests/common
+++ b/tests/qemu-iotests/common
@@ -158,6 +158,7 @@ check options
     -nfs                test nfs
     -archipelago        test archipelago
     -luks               test luks
+    -vxhs               test vxhs
     -xdiff              graphical mode diff
     -nocache            use O_DIRECT on backing file
     -misalign           misalign memory allocations
@@ -261,6 +262,11 @@ testlist options
             xpand=false
             ;;
 
+        -vxhs)
+            IMGPROTO=vxhs
+            xpand=false
+            ;;
+
         -ssh)
             IMGPROTO=ssh
             xpand=false
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index f6384fb..c7a80c0 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -105,6 +105,10 @@ if [ -z "$QEMU_NBD_PROG" ]; then
     export QEMU_NBD_PROG="`set_prog_path qemu-nbd`"
 fi
 
+if [ -z "$QEMU_VXHS_PROG" ]; then
+    export QEMU_VXHS_PROG="`set_prog_path qnio_server /usr/local/bin`"
+fi
+
 _qemu_wrapper()
 {
     (
@@ -156,10 +160,19 @@ _qemu_nbd_wrapper()
     )
 }
 
+_qemu_vxhs_wrapper()
+{
+    (
+        echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
+        exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
+    )
+}
+
 export QEMU=_qemu_wrapper
 export QEMU_IMG=_qemu_img_wrapper
 export QEMU_IO=_qemu_io_wrapper
 export QEMU_NBD=_qemu_nbd_wrapper
+export QEMU_VXHS=_qemu_vxhs_wrapper
 
 QEMU_IMG_EXTRA_ARGS=
 if [ "$IMGOPTSSYNTAX" = "true" ]; then
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 240ed06..a8a4d0e 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -123,6 +123,7 @@ _filter_img_info()
         -e "s#$TEST_DIR#TEST_DIR#g" \
         -e "s#$IMGFMT#IMGFMT#g" \
         -e 's#nbd://127.0.0.1:10810$#TEST_DIR/t.IMGFMT#g' \
+        -e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \
         -e "/encrypted: yes/d" \
         -e "/cluster_size: [0-9]\\+/d" \
         -e "/table_size: [0-9]\\+/d" \
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 3213765..06a3164 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -89,6 +89,9 @@ else
         TEST_IMG=$TEST_DIR/t.$IMGFMT
     elif [ "$IMGPROTO" = "archipelago" ]; then
         TEST_IMG="archipelago:at.$IMGFMT"
+    elif [ "$IMGPROTO" = "vxhs" ]; then
+        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
+        TEST_IMG="vxhs://127.0.0.1:9999/t.$IMGFMT"
     else
         TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
     fi
@@ -175,6 +178,12 @@ _make_test_img()
         eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT  $TEST_IMG_FILE &"
         sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
     fi
+
+    # Start QNIO server on image directory for vxhs protocol
+    if [ $IMGPROTO = "vxhs" ]; then
+        eval "$QEMU_VXHS -d  $TEST_DIR &"
+        sleep 1 # Wait for server to come up.
+    fi
 }
 
 _rm_test_img()
@@ -201,6 +210,16 @@ _cleanup_test_img()
             fi
             rm -f "$TEST_IMG_FILE"
             ;;
+        vxhs)
+            if [ -f "${TEST_DIR}/qemu-vxhs.pid" ]; then
+                local QEMU_VXHS_PID
+                read QEMU_VXHS_PID < "${TEST_DIR}/qemu-vxhs.pid"
+                kill ${QEMU_VXHS_PID} >/dev/null 2>&1
+                rm -f "${TEST_DIR}/qemu-vxhs.pid"
+            fi
+            rm -f "$TEST_IMG_FILE"
+            ;;
+
         file)
             _rm_test_img "$TEST_DIR/t.$IMGFMT"
             _rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09  5:23 [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Ashish Mittal
  2017-02-09  5:23 ` [Qemu-devel] [PATCH v8 2/2] block/vxhs.c: Add qemu-iotests for new block device type "vxhs" Ashish Mittal
@ 2017-02-09  6:29 ` Jeff Cody
  2017-02-09  9:24   ` ashish mittal
  1 sibling, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-09  6:29 UTC (permalink / raw)
  To: Ashish Mittal
  Cc: qemu-devel, pbonzini, kwolf, armbru, berrange, famz,
	ashish.mittal, stefanha, jferlan, Buddhi.Madhav, Suraj.Singh,
	Nitin.Jerath, peter.maydell, Ketan.Nilangekar, Abhijit.Dey

On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
> From: Ashish Mittal <ashish.mittal@veritas.com>
> 
> Source code for the qnio library that this code loads can be downloaded from:
> https://github.com/VeritasHyperScale/libqnio.git
> 
> Sample command line using JSON syntax:
> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
> -msg timestamp=on
> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
> "server":{"host":"172.172.17.4","port":"9999"}}'
> 
> Sample command line using URI syntax:
> qemu-img convert -f raw -O raw -n
> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>

I don't know if I am using the qnio_server test server correctly or not, but
when I run qemu-io from the command line I get an i/o error.  When I run the
qemu-iotests, I get a segfault.

Were you able to run qemu-iotests with these patches?

Here is how I am invoking qnio_server:

# qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v



> Signed-off-by: Ashish Mittal <ashish.mittal@veritas.com>
> ---
> TODO:
> (1) valgrind report to follow soon.
> 
> v8 changelog:
> (1) Security implementation for libqnio present in branch 'securify'.
>     Please use 'securify' branch for building libqnio and testing
>     with this patch.
> (2) Renamed libqnio to libvxhs.
> (3) Pass instance ID to libvxhs for SSL authentication.
> 
> v7 changelog:
> (1) IO failover code has moved out to the libqnio library.
> (2) Fixes for issues reported by Stefan on v6.
> (3) Incorporated the QEMUBH patch provided by Stefan.
>     This is a replacement for the pipe mechanism used earlier.
> (4) Fixes to the buffer overflows reported in libqnio.
> (5) Input validations in vxhs.c to prevent any buffer overflows for 
>     arguments passed to libqnio.
> 
> v6 changelog:
> (1) Added qemu-iotests for VxHS as a new patch in the series.
> (2) Replaced release version from 2.8 to 2.9 in block-core.json.
> 
> v5 changelog:
> (1) Incorporated v4 review comments.
> 
> v4 changelog:
> (1) Incorporated v3 review comments on QAPI changes.
> (2) Added refcounting for device open/close.
>     Free library resources on last device close.
> 
> v3 changelog:
> (1) Added QAPI schema for the VxHS driver.
> 
> v2 changelog:
> (1) Changes done in response to v1 comments.
> 
>  block/Makefile.objs  |   2 +
>  block/trace-events   |  16 ++
>  block/vxhs.c         | 499 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  configure            |  41 +++++
>  qapi/block-core.json |  20 ++-
>  5 files changed, 576 insertions(+), 2 deletions(-)
>  create mode 100644 block/vxhs.c
> 
> diff --git a/block/Makefile.objs b/block/Makefile.objs
> index c6bd14e..75675b4 100644
> --- a/block/Makefile.objs
> +++ b/block/Makefile.objs
> @@ -19,6 +19,7 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
>  block-obj-$(CONFIG_CURL) += curl.o
>  block-obj-$(CONFIG_RBD) += rbd.o
>  block-obj-$(CONFIG_GLUSTERFS) += gluster.o
> +block-obj-$(CONFIG_VXHS) += vxhs.o
>  block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
>  block-obj-$(CONFIG_LIBSSH2) += ssh.o
>  block-obj-y += accounting.o dirty-bitmap.o
> @@ -39,6 +40,7 @@ rbd.o-cflags       := $(RBD_CFLAGS)
>  rbd.o-libs         := $(RBD_LIBS)
>  gluster.o-cflags   := $(GLUSTERFS_CFLAGS)
>  gluster.o-libs     := $(GLUSTERFS_LIBS)
> +vxhs.o-libs        := $(VXHS_LIBS)
>  ssh.o-cflags       := $(LIBSSH2_CFLAGS)
>  ssh.o-libs         := $(LIBSSH2_LIBS)
>  archipelago.o-libs := $(ARCHIPELAGO_LIBS)
> diff --git a/block/trace-events b/block/trace-events
> index 0bc5c0a..d5eca93 100644
> --- a/block/trace-events
> +++ b/block/trace-events
> @@ -110,3 +110,19 @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
>  qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
>  qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
>  qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
> +
> +# block/vxhs.c
> +vxhs_iio_callback(int error) "ctx is NULL: error %d"
> +vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
> +vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
> +vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
> +vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu offset = %lu ACB = %p. Error = %d, errno = %d"
> +vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
> +vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %lu"
> +vxhs_qnio_iio_open(const char *ip) "Failed to connect to storage agent on host-ip %s"
> +vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld"
> +vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
> +vxhs_qemu_init_vdisk(const char *vdisk_id) "vdisk-id from json %s"
> +vxhs_parse_uri_hostinfo(int num, char *host, int port) "Host %d: IP %s, Port %d"
> +vxhs_qemu_init(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
> +vxhs_close(char *vdisk_guid) "Closing vdisk %s"
> diff --git a/block/vxhs.c b/block/vxhs.c
> new file mode 100644
> index 0000000..f1b5f1c
> --- /dev/null
> +++ b/block/vxhs.c
> @@ -0,0 +1,499 @@
> +/*
> + * QEMU Block driver for Veritas HyperScale (VxHS)
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include <qnio/qnio_api.h>
> +#include <sys/param.h>
> +#include "block/block_int.h"
> +#include "qapi/qmp/qerror.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qstring.h"
> +#include "trace.h"
> +#include "qemu/uri.h"
> +#include "qapi/error.h"
> +#include "qemu/uuid.h"
> +
> +#define VXHS_OPT_FILENAME           "filename"
> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
> +#define VXHS_OPT_SERVER             "server"
> +#define VXHS_OPT_HOST               "host"
> +#define VXHS_OPT_PORT               "port"
> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"

What is this?  It is not a valid UUID; is the value significant?

> +
> +QemuUUID qemu_uuid __attribute__ ((weak));

I have questions on this later, at [1]

> +
> +static int lib_init_failed;

With a ref count, I think this can go away.

> +
> +typedef enum {
> +    VDISK_AIO_READ,
> +    VDISK_AIO_WRITE,
> +} VDISKAIOCmd;
> +
> +/*
> + * HyperScale AIO callbacks structure
> + */
> +typedef struct VXHSAIOCB {
> +    BlockAIOCB common;
> +    int err;
> +    QEMUIOVector *qiov;
> +} VXHSAIOCB;
> +
> +typedef struct VXHSvDiskHostsInfo {
> +    void *dev_handle; /* Device handle */
> +    char *host; /* Host name or IP */
> +    int port; /* Host's port number */
> +} VXHSvDiskHostsInfo;
> +
> +/*
> + * Structure per vDisk maintained for state
> + */
> +typedef struct BDRVVXHSState {
> +    VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
> +    char *vdisk_guid;
> +} BDRVVXHSState;
> +
> +static void vxhs_complete_aio_bh(void *opaque)
> +{
> +    VXHSAIOCB *acb = opaque;
> +    BlockCompletionFunc *cb = acb->common.cb;
> +    void *cb_opaque = acb->common.opaque;
> +    int ret = 0;
> +
> +    if (acb->err != 0) {
> +        trace_vxhs_complete_aio(acb, acb->err);
> +        ret = (-EIO);
> +    }
> +
> +    qemu_aio_unref(acb);
> +    cb(cb_opaque, ret);
> +}
> +
> +/*
> + * Called from a libqnio thread
> + */
> +static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
> +{
> +    VXHSAIOCB *acb = NULL;
> +
> +    switch (opcode) {
> +    case IRP_READ_REQUEST:
> +    case IRP_WRITE_REQUEST:
> +
> +        /*
> +         * ctx is VXHSAIOCB*
> +         * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
> +         */
> +        if (ctx) {
> +            acb = ctx;
> +        } else {
> +            trace_vxhs_iio_callback(error);
> +            goto out;
> +        }
> +
> +        if (error) {
> +            if (!acb->err) {
> +                acb->err = error;
> +            }
> +            trace_vxhs_iio_callback(error);
> +        }
> +
> +        aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
> +                                vxhs_complete_aio_bh, acb);
> +        break;
> +
> +    default:
> +        if (error == QNIOERROR_HUP) {
> +            /*
> +             * Channel failed, spontaneous notification,
> +             * not in response to I/O
> +             */
> +            trace_vxhs_iio_callback_chnfail(error, errno);
> +        } else {
> +            trace_vxhs_iio_callback_unknwn(opcode, error);
> +        }
> +        break;
> +    }
> +out:
> +    return;
> +}
> +
> +static QemuOptsList runtime_opts = {
> +    .name = "vxhs",
> +    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
> +    .desc = {
> +        {
> +            .name = VXHS_OPT_FILENAME,
> +            .type = QEMU_OPT_STRING,
> +            .help = "URI to the Veritas HyperScale image",
> +        },
> +        {
> +            .name = VXHS_OPT_VDISK_ID,
> +            .type = QEMU_OPT_STRING,
> +            .help = "UUID of the VxHS vdisk",
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
> +static QemuOptsList runtime_tcp_opts = {
> +    .name = "vxhs_tcp",
> +    .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
> +    .desc = {
> +        {
> +            .name = VXHS_OPT_HOST,
> +            .type = QEMU_OPT_STRING,
> +            .help = "host address (ipv4 addresses)",
> +        },
> +        {
> +            .name = VXHS_OPT_PORT,
> +            .type = QEMU_OPT_NUMBER,
> +            .help = "port number on which VxHSD is listening (default 9999)",
> +            .def_value_str = "9999"
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
> +/*
> + * Parse the incoming URI and populate *options with the host information.
> + * URI syntax has the limitation of supporting only one host info.
> + * To pass multiple host information, use the JSON syntax.
> + */
> +static int vxhs_parse_uri(const char *filename, QDict *options)
> +{
> +    URI *uri = NULL;
> +    char *hoststr, *portstr;
> +    char *port;
> +    int ret = 0;
> +
> +    trace_vxhs_parse_uri_filename(filename);
> +    uri = uri_parse(filename);
> +    if (!uri || !uri->server || !uri->path) {
> +        uri_free(uri);
> +        return -EINVAL;
> +    }
> +
> +    hoststr = g_strdup(VXHS_OPT_SERVER".host");
> +    qdict_put(options, hoststr, qstring_from_str(uri->server));
> +    g_free(hoststr);
> +
> +    portstr = g_strdup(VXHS_OPT_SERVER".port");
> +    if (uri->port) {
> +        port = g_strdup_printf("%d", uri->port);
> +        qdict_put(options, portstr, qstring_from_str(port));
> +        g_free(port);
> +    }
> +    g_free(portstr);
> +
> +    if (strstr(uri->path, "vxhs") == NULL) {
> +        qdict_put(options, "vdisk-id", qstring_from_str(uri->path));
> +    }
> +
> +    trace_vxhs_parse_uri_hostinfo(1, uri->server, uri->port);
> +    uri_free(uri);
> +
> +    return ret;
> +}
> +
> +static void vxhs_parse_filename(const char *filename, QDict *options,
> +                                Error **errp)
> +{
> +    if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
> +        error_setg(errp, "vdisk-id/server and a file name may not be specified "
> +                         "at the same time");
> +        return;
> +    }
> +
> +    if (strstr(filename, "://")) {
> +        int ret = vxhs_parse_uri(filename, options);
> +        if (ret < 0) {
> +            error_setg(errp, "Invalid URI. URI should be of the form "
> +                       "  vxhs://<host_ip>:<port>/<vdisk-id>");
> +        }
> +    }
> +}
> +
> +static int vxhs_open(BlockDriverState *bs, QDict *options,
> +                     int bdrv_flags, Error **errp)
> +{
> +    BDRVVXHSState *s = bs->opaque;
> +    void *dev_handlep = NULL;
> +    QDict *backing_options = NULL;
> +    QemuOpts *opts, *tcp_opts;
> +    char *of_vsa_addr = NULL;
> +    Error *local_err = NULL;
> +    const char *vdisk_id_opt;
> +    const char *server_host_opt;
> +    char *str = NULL;
> +    int ret = 0;
> +
> +    if (lib_init_failed) {
> +        return -ENODEV;
> +    }

Since you can't call iio_init() in the bdrv_vxhs_init() function [1],
instead of the above you can just use a refcnt, and call iio_init when the
refcnt is 0.


> +    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
> +    qemu_opts_absorb_qdict(opts, options, &local_err);
> +    if (local_err) {
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    /* vdisk-id is the disk UUID */
> +    vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
> +    if (!vdisk_id_opt) {
> +        error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    /* vdisk-id may contain a leading '/' */
> +    if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
> +        error_setg(errp, "vdisk-id cannot be more than %d characters",

You are propagating local_err in the error handler "out:" via
error_propagate() for all the other cases, but setting errp directly here.
That will happen to work out, because local_err will be NULL and
error_propagate() will be a NOOP in that case, but it probably isn't what
you intended.  You should set &local_err, like in the other error cases.

> +                   UUID_FMT_LEN);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    s->vdisk_guid = g_strdup(vdisk_id_opt);
> +    trace_vxhs_qemu_init_vdisk(vdisk_id_opt);
> +
> +    str = g_strdup_printf(VXHS_OPT_SERVER".");
> +    qdict_extract_subqdict(options, &backing_options, str);
> +
> +    /* Create opts info from runtime_tcp_opts list */
> +    tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
> +    qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
> +    if (local_err) {
> +        qdict_del(backing_options, str);
> +        qemu_opts_del(tcp_opts);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
> +    if (!server_host_opt) {
> +        error_setg(&local_err, QERR_MISSING_PARAMETER,
> +                   VXHS_OPT_SERVER"."VXHS_OPT_HOST);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
> +        error_setg(errp, "server.host cannot be more than %d characters",
> +                   MAXHOSTNAMELEN);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
> +
> +    s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
> +                                                          VXHS_OPT_PORT),
> +                                                          NULL, 0);
> +
> +    trace_vxhs_qemu_init(s->vdisk_hostinfo.host,
> +                         s->vdisk_hostinfo.port);
> +
> +    qdict_del(backing_options, str);
> +    qemu_opts_del(tcp_opts);
> +
> +    of_vsa_addr = g_strdup_printf("of://%s:%d",
> +                                s->vdisk_hostinfo.host,
> +                                s->vdisk_hostinfo.port);
> +
> +    /*
> +     * Open qnio channel to storage agent if not opened before.
> +     */
> +    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0);
> +    if (dev_handlep == NULL) {
> +        trace_vxhs_qnio_iio_open(of_vsa_addr);
> +        ret = -ENODEV;
> +        goto out;
> +    }
> +    s->vdisk_hostinfo.dev_handle = dev_handlep;
> +
> +out:
> +    g_free(str);
> +    g_free(of_vsa_addr);
> +    QDECREF(backing_options);
> +    qemu_opts_del(opts);
> +
> +    if (ret < 0) {
> +        error_propagate(errp, local_err);
> +        g_free(s->vdisk_hostinfo.host);
> +        g_free(s->vdisk_guid);
> +        s->vdisk_guid = NULL;
> +        errno = -ret;
> +    }
> +
> +    return ret;
> +}
> +
> +static const AIOCBInfo vxhs_aiocb_info = {
> +    .aiocb_size = sizeof(VXHSAIOCB)
> +};
> +
> +/*
> + * This allocates QEMU-VXHS callback for each IO
> + * and is passed to QNIO. When QNIO completes the work,
> + * it will be passed back through the callback.
> + */
> +static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
> +                               QEMUIOVector *qiov, int nb_sectors,
> +                               BlockCompletionFunc *cb, void *opaque,
> +                               VDISKAIOCmd iodir)
> +{
> +    VXHSAIOCB *acb = NULL;
> +    BDRVVXHSState *s = bs->opaque;
> +    size_t size;
> +    uint64_t offset;
> +    int iio_flags = 0;
> +    int ret = 0;
> +    void *dev_handle = s->vdisk_hostinfo.dev_handle;
> +
> +    offset = sector_num * BDRV_SECTOR_SIZE;
> +    size = nb_sectors * BDRV_SECTOR_SIZE;
> +    acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
> +
> +    /*
> +     * Initialize VXHSAIOCB.
> +     */
> +    acb->err = 0;
> +    acb->qiov = qiov;
> +
> +    iio_flags = IIO_FLAG_ASYNC;
> +
> +    switch (iodir) {
> +    case VDISK_AIO_WRITE:
> +            ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
> +                             offset, (uint64_t)size, iio_flags);
> +            break;
> +    case VDISK_AIO_READ:
> +            ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
> +                            offset, (uint64_t)size, iio_flags);
> +            break;
> +    default:
> +            trace_vxhs_aio_rw_invalid(iodir);
> +            goto errout;
> +    }
> +
> +    if (ret != 0) {
> +        trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
> +                                acb, ret, errno);
> +        goto errout;
> +    }
> +    return &acb->common;
> +
> +errout:
> +    qemu_aio_unref(acb);
> +    return NULL;
> +}
> +
> +static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
> +                                   int64_t sector_num, QEMUIOVector *qiov,
> +                                   int nb_sectors,
> +                                   BlockCompletionFunc *cb, void *opaque)
> +{
> +    return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
> +                       opaque, VDISK_AIO_READ);
> +}
> +
> +static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
> +                                   int64_t sector_num, QEMUIOVector *qiov,
> +                                   int nb_sectors,
> +                                   BlockCompletionFunc *cb, void *opaque)
> +{
> +    return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
> +                       cb, opaque, VDISK_AIO_WRITE);
> +}
> +
> +static void vxhs_close(BlockDriverState *bs)
> +{
> +    BDRVVXHSState *s = bs->opaque;
> +
> +    trace_vxhs_close(s->vdisk_guid);
> +
> +    g_free(s->vdisk_guid);
> +    s->vdisk_guid = NULL;
> +
> +    /*
> +     * Close vDisk device
> +     */
> +    if (s->vdisk_hostinfo.dev_handle) {
> +        iio_close(s->vdisk_hostinfo.dev_handle);
> +        s->vdisk_hostinfo.dev_handle = NULL;
> +    }
> +
> +    /*
> +     * Free the dynamically allocated host string
> +     */
> +    g_free(s->vdisk_hostinfo.host);
> +    s->vdisk_hostinfo.host = NULL;
> +    s->vdisk_hostinfo.port = 0;

If you use a static vxhs iio refcnt, you can decrement it here and call
iio_fini (which is now currently never called) to free resources.


> +}
> +
> +static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
> +{
> +    int64_t vdisk_size = -1;
> +    int ret = 0;
> +    void *dev_handle = s->vdisk_hostinfo.dev_handle;
> +
> +    ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
> +    if (ret < 0) {
> +        trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
> +        return -EIO;
> +    }
> +
> +    trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
> +    return vdisk_size;
> +}
> +
> +/*
> + * Returns the size of vDisk in bytes. This is required
> + * by QEMU block upper block layer so that it is visible
> + * to guest.
> + */
> +static int64_t vxhs_getlength(BlockDriverState *bs)
> +{
> +    BDRVVXHSState *s = bs->opaque;
> +    int64_t vdisk_size;
> +
> +    vdisk_size = vxhs_get_vdisk_stat(s);
> +    if (vdisk_size < 0) {
> +        return -EIO;
> +    }
> +
> +    return vdisk_size;
> +}
> +
> +static BlockDriver bdrv_vxhs = {
> +    .format_name                  = "vxhs",
> +    .protocol_name                = "vxhs",
> +    .instance_size                = sizeof(BDRVVXHSState),
> +    .bdrv_file_open               = vxhs_open,
> +    .bdrv_parse_filename          = vxhs_parse_filename,
> +    .bdrv_close                   = vxhs_close,
> +    .bdrv_getlength               = vxhs_getlength,
> +    .bdrv_aio_readv               = vxhs_aio_readv,
> +    .bdrv_aio_writev              = vxhs_aio_writev,
> +};
> +
> +static void bdrv_vxhs_init(void)
> +{
> +    char out[37];
> +
> +    if (qemu_uuid_is_null(&qemu_uuid)) {
> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
> +    } else {
> +        qemu_uuid_unparse(&qemu_uuid, out);
> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
> +    }
> +

[1]

Can you explain what is going on here with the qemu_uuid check?


You also can't do this here.  This init function is just to register the
driver (e.g. populate the BlockDriver list).  You shouldn't be doing
anything other than the bdrv_register() call here.

Since you want to run this iio_init only once, I would recommend doing it in
the vxhs_open() call, and using a ref counter.  That way, you can also call
iio_fini() to finish releasing resources once the last device is closed.

This was actually a suggestion I had before, which you then incorporated
into v6, but it appears all the refcnt code has gone away for v7/v8.


> +    bdrv_register(&bdrv_vxhs);
> +}
> +
> +block_init(bdrv_vxhs_init);
> diff --git a/configure b/configure
> index 6325339..c3ccf02 100755
> --- a/configure
> +++ b/configure
> @@ -321,6 +321,7 @@ numa=""
>  tcmalloc="no"
>  jemalloc="no"
>  replication="yes"
> +vxhs=""
>  
>  # parse CC options first
>  for opt do
> @@ -1170,6 +1171,10 @@ for opt do
>    ;;
>    --enable-replication) replication="yes"
>    ;;
> +  --disable-vxhs) vxhs="no"
> +  ;;
> +  --enable-vxhs) vxhs="yes"
> +  ;;
>    *)
>        echo "ERROR: unknown option $opt"
>        echo "Try '$0 --help' for more information"
> @@ -1403,6 +1408,7 @@ disabled with --disable-FEATURE, default is enabled if available:
>    tcmalloc        tcmalloc support
>    jemalloc        jemalloc support
>    replication     replication support
> +  vxhs            Veritas HyperScale vDisk backend support
>  
>  NOTE: The object files are built at the place where configure is launched
>  EOF
> @@ -4748,6 +4754,34 @@ if test "$modules" = "yes" && test "$LD_REL_FLAGS" = ""; then
>  fi
>  
>  ##########################################
> +# Veritas HyperScale block driver VxHS
> +# Check if libvxhs is installed
> +
> +if test "$vxhs" != "no" ; then
> +  cat > $TMPC <<EOF
> +#include <stdint.h>
> +#include <qnio/qnio_api.h>
> +
> +#define VXHS_UUID "12345678-1234-1234-1234-123456789012"
> +void *vxhs_callback;
> +
> +int main(void) {
> +    iio_init(QNIO_VERSION, vxhs_callback, VXHS_UUID);
> +    return 0;
> +}
> +EOF
> +  vxhs_libs="-lvxhs -lssl"
> +  if compile_prog "" "$vxhs_libs" ; then
> +    vxhs=yes
> +  else
> +    if test "$vxhs" = "yes" ; then
> +      feature_not_found "vxhs block device" "Install libvxhs See github"
> +    fi
> +    vxhs=no
> +  fi
> +fi
> +
> +##########################################
>  # End of CC checks
>  # After here, no more $cc or $ld runs
>  
> @@ -5114,6 +5148,7 @@ echo "tcmalloc support  $tcmalloc"
>  echo "jemalloc support  $jemalloc"
>  echo "avx2 optimization $avx2_opt"
>  echo "replication support $replication"
> +echo "VxHS block device $vxhs"
>  
>  if test "$sdl_too_old" = "yes"; then
>  echo "-> Your SDL version is too old - please upgrade to have SDL support"
> @@ -5729,6 +5764,12 @@ if test "$pthread_setname_np" = "yes" ; then
>    echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak
>  fi
>  
> +if test "$vxhs" = "yes" ; then
> +  echo "CONFIG_VXHS=y" >> $config_host_mak
> +  echo "VXHS_CFLAGS=$vxhs_cflags" >> $config_host_mak
> +  echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
> +fi
> +
>  if test "$tcg_interpreter" = "yes"; then
>    QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
>  elif test "$ARCH" = "sparc64" ; then
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 932f5bb..f37df56 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -2110,6 +2110,7 @@
>  # @nfs: Since 2.8
>  # @replication: Since 2.8
>  # @ssh: Since 2.8
> +# @vxhs: Since 2.9
>  #
>  # Since: 2.0
>  ##
> @@ -2119,7 +2120,7 @@
>              'host_device', 'http', 'https', 'luks', 'nbd', 'nfs', 'null-aio',
>              'null-co', 'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw',
>              'replication', 'ssh', 'vdi', 'vhdx', 'vmdk', 'vpc',
> -            'vvfat' ] }
> +            'vvfat','vxhs' ] }
>  
>  ##
>  # @BlockdevOptionsFile:
> @@ -2744,6 +2745,20 @@
>    'data': { '*offset': 'int', '*size': 'int' } }
>  
>  ##
> +# @BlockdevOptionsVxHS:
> +#
> +# Driver specific block device options for VxHS
> +#
> +# @vdisk-id:    UUID of VxHS volume
> +# @server:      vxhs server IP, port
> +#
> +# Since: 2.9
> +##
> +{ 'struct': 'BlockdevOptionsVxHS',
> +  'data': { 'vdisk-id': 'str',
> +            'server': 'InetSocketAddress' } }
> +
> +##
>  # @BlockdevOptions:
>  #
>  # Options for creating a block device.  Many options are available for all
> @@ -2806,7 +2821,8 @@
>        'vhdx':       'BlockdevOptionsGenericFormat',
>        'vmdk':       'BlockdevOptionsGenericCOWFormat',
>        'vpc':        'BlockdevOptionsGenericFormat',
> -      'vvfat':      'BlockdevOptionsVVFAT'
> +      'vvfat':      'BlockdevOptionsVVFAT',
> +      'vxhs':       'BlockdevOptionsVxHS'
>    } }
>  
>  ##
> -- 
> 1.8.3.1
> 

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09  6:29 ` [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Jeff Cody
@ 2017-02-09  9:24   ` ashish mittal
  2017-02-09 14:32     ` Jeff Cody
  2017-02-14 20:51     ` Jeff Cody
  0 siblings, 2 replies; 56+ messages in thread
From: ashish mittal @ 2017-02-09  9:24 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
> On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>> From: Ashish Mittal <ashish.mittal@veritas.com>
>>
>> Source code for the qnio library that this code loads can be downloaded from:
>> https://github.com/VeritasHyperScale/libqnio.git
>>
>> Sample command line using JSON syntax:
>> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>> -msg timestamp=on
>> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>> "server":{"host":"172.172.17.4","port":"9999"}}'
>>
>> Sample command line using URI syntax:
>> qemu-img convert -f raw -O raw -n
>> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>>
>
> I don't know if I am using the qnio_server test server correctly or not, but
> when I run qemu-io from the command line I get an i/o error.  When I run the
> qemu-iotests, I get a segfault.
>
> Were you able to run qemu-iotests with these patches?
>
> Here is how I am invoking qnio_server:
>
> # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
>
>

I ran full qemu-iotests and qemu-io manually with the test server on
version 7 patches. Ran qemu-io manually with the test server on
version 8, but the libvxhs code is undergoing a lot of checkins. Will
test again tomorrow and get back.

>
>> Signed-off-by: Ashish Mittal <ashish.mittal@veritas.com>
>> ---
>> TODO:
>> (1) valgrind report to follow soon.
>>
>> v8 changelog:
>> (1) Security implementation for libqnio present in branch 'securify'.
>>     Please use 'securify' branch for building libqnio and testing
>>     with this patch.
>> (2) Renamed libqnio to libvxhs.
>> (3) Pass instance ID to libvxhs for SSL authentication.
>>
>> v7 changelog:
>> (1) IO failover code has moved out to the libqnio library.
>> (2) Fixes for issues reported by Stefan on v6.
>> (3) Incorporated the QEMUBH patch provided by Stefan.
>>     This is a replacement for the pipe mechanism used earlier.
>> (4) Fixes to the buffer overflows reported in libqnio.
>> (5) Input validations in vxhs.c to prevent any buffer overflows for
>>     arguments passed to libqnio.
>>
>> v6 changelog:
>> (1) Added qemu-iotests for VxHS as a new patch in the series.
>> (2) Replaced release version from 2.8 to 2.9 in block-core.json.
>>
>> v5 changelog:
>> (1) Incorporated v4 review comments.
>>
>> v4 changelog:
>> (1) Incorporated v3 review comments on QAPI changes.
>> (2) Added refcounting for device open/close.
>>     Free library resources on last device close.
>>
>> v3 changelog:
>> (1) Added QAPI schema for the VxHS driver.
>>
>> v2 changelog:
>> (1) Changes done in response to v1 comments.
>>
>>  block/Makefile.objs  |   2 +
>>  block/trace-events   |  16 ++
>>  block/vxhs.c         | 499 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  configure            |  41 +++++
>>  qapi/block-core.json |  20 ++-
>>  5 files changed, 576 insertions(+), 2 deletions(-)
>>  create mode 100644 block/vxhs.c
>>
>> diff --git a/block/Makefile.objs b/block/Makefile.objs
>> index c6bd14e..75675b4 100644
>> --- a/block/Makefile.objs
>> +++ b/block/Makefile.objs
>> @@ -19,6 +19,7 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
>>  block-obj-$(CONFIG_CURL) += curl.o
>>  block-obj-$(CONFIG_RBD) += rbd.o
>>  block-obj-$(CONFIG_GLUSTERFS) += gluster.o
>> +block-obj-$(CONFIG_VXHS) += vxhs.o
>>  block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
>>  block-obj-$(CONFIG_LIBSSH2) += ssh.o
>>  block-obj-y += accounting.o dirty-bitmap.o
>> @@ -39,6 +40,7 @@ rbd.o-cflags       := $(RBD_CFLAGS)
>>  rbd.o-libs         := $(RBD_LIBS)
>>  gluster.o-cflags   := $(GLUSTERFS_CFLAGS)
>>  gluster.o-libs     := $(GLUSTERFS_LIBS)
>> +vxhs.o-libs        := $(VXHS_LIBS)
>>  ssh.o-cflags       := $(LIBSSH2_CFLAGS)
>>  ssh.o-libs         := $(LIBSSH2_LIBS)
>>  archipelago.o-libs := $(ARCHIPELAGO_LIBS)
>> diff --git a/block/trace-events b/block/trace-events
>> index 0bc5c0a..d5eca93 100644
>> --- a/block/trace-events
>> +++ b/block/trace-events
>> @@ -110,3 +110,19 @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
>>  qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
>>  qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
>>  qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
>> +
>> +# block/vxhs.c
>> +vxhs_iio_callback(int error) "ctx is NULL: error %d"
>> +vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
>> +vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
>> +vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
>> +vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu offset = %lu ACB = %p. Error = %d, errno = %d"
>> +vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
>> +vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %lu"
>> +vxhs_qnio_iio_open(const char *ip) "Failed to connect to storage agent on host-ip %s"
>> +vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld"
>> +vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
>> +vxhs_qemu_init_vdisk(const char *vdisk_id) "vdisk-id from json %s"
>> +vxhs_parse_uri_hostinfo(int num, char *host, int port) "Host %d: IP %s, Port %d"
>> +vxhs_qemu_init(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
>> +vxhs_close(char *vdisk_guid) "Closing vdisk %s"
>> diff --git a/block/vxhs.c b/block/vxhs.c
>> new file mode 100644
>> index 0000000..f1b5f1c
>> --- /dev/null
>> +++ b/block/vxhs.c
>> @@ -0,0 +1,499 @@
>> +/*
>> + * QEMU Block driver for Veritas HyperScale (VxHS)
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + *
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include <qnio/qnio_api.h>
>> +#include <sys/param.h>
>> +#include "block/block_int.h"
>> +#include "qapi/qmp/qerror.h"
>> +#include "qapi/qmp/qdict.h"
>> +#include "qapi/qmp/qstring.h"
>> +#include "trace.h"
>> +#include "qemu/uri.h"
>> +#include "qapi/error.h"
>> +#include "qemu/uuid.h"
>> +
>> +#define VXHS_OPT_FILENAME           "filename"
>> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
>> +#define VXHS_OPT_SERVER             "server"
>> +#define VXHS_OPT_HOST               "host"
>> +#define VXHS_OPT_PORT               "port"
>> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
>
> What is this?  It is not a valid UUID; is the value significant?
>

This value gets passed to libvxhs for binaries like qemu-io, qemu-img
that do not have an Instance ID. We can use this default ID to control
access to specific vdisks by these binaries. qemu-kvm will pass the
actual instance ID, and therefore will not use this default value.

Will reply to other queries soon.

>> +
>> +QemuUUID qemu_uuid __attribute__ ((weak));
>
> I have questions on this later, at [1]
>
>> +
>> +static int lib_init_failed;
>
> With a ref count, I think this can go away.
>
>> +
>> +typedef enum {
>> +    VDISK_AIO_READ,
>> +    VDISK_AIO_WRITE,
>> +} VDISKAIOCmd;
>> +
>> +/*
>> + * HyperScale AIO callbacks structure
>> + */
>> +typedef struct VXHSAIOCB {
>> +    BlockAIOCB common;
>> +    int err;
>> +    QEMUIOVector *qiov;
>> +} VXHSAIOCB;
>> +
>> +typedef struct VXHSvDiskHostsInfo {
>> +    void *dev_handle; /* Device handle */
>> +    char *host; /* Host name or IP */
>> +    int port; /* Host's port number */
>> +} VXHSvDiskHostsInfo;
>> +
>> +/*
>> + * Structure per vDisk maintained for state
>> + */
>> +typedef struct BDRVVXHSState {
>> +    VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
>> +    char *vdisk_guid;
>> +} BDRVVXHSState;
>> +
>> +static void vxhs_complete_aio_bh(void *opaque)
>> +{
>> +    VXHSAIOCB *acb = opaque;
>> +    BlockCompletionFunc *cb = acb->common.cb;
>> +    void *cb_opaque = acb->common.opaque;
>> +    int ret = 0;
>> +
>> +    if (acb->err != 0) {
>> +        trace_vxhs_complete_aio(acb, acb->err);
>> +        ret = (-EIO);
>> +    }
>> +
>> +    qemu_aio_unref(acb);
>> +    cb(cb_opaque, ret);
>> +}
>> +
>> +/*
>> + * Called from a libqnio thread
>> + */
>> +static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
>> +{
>> +    VXHSAIOCB *acb = NULL;
>> +
>> +    switch (opcode) {
>> +    case IRP_READ_REQUEST:
>> +    case IRP_WRITE_REQUEST:
>> +
>> +        /*
>> +         * ctx is VXHSAIOCB*
>> +         * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
>> +         */
>> +        if (ctx) {
>> +            acb = ctx;
>> +        } else {
>> +            trace_vxhs_iio_callback(error);
>> +            goto out;
>> +        }
>> +
>> +        if (error) {
>> +            if (!acb->err) {
>> +                acb->err = error;
>> +            }
>> +            trace_vxhs_iio_callback(error);
>> +        }
>> +
>> +        aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
>> +                                vxhs_complete_aio_bh, acb);
>> +        break;
>> +
>> +    default:
>> +        if (error == QNIOERROR_HUP) {
>> +            /*
>> +             * Channel failed, spontaneous notification,
>> +             * not in response to I/O
>> +             */
>> +            trace_vxhs_iio_callback_chnfail(error, errno);
>> +        } else {
>> +            trace_vxhs_iio_callback_unknwn(opcode, error);
>> +        }
>> +        break;
>> +    }
>> +out:
>> +    return;
>> +}
>> +
>> +static QemuOptsList runtime_opts = {
>> +    .name = "vxhs",
>> +    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
>> +    .desc = {
>> +        {
>> +            .name = VXHS_OPT_FILENAME,
>> +            .type = QEMU_OPT_STRING,
>> +            .help = "URI to the Veritas HyperScale image",
>> +        },
>> +        {
>> +            .name = VXHS_OPT_VDISK_ID,
>> +            .type = QEMU_OPT_STRING,
>> +            .help = "UUID of the VxHS vdisk",
>> +        },
>> +        { /* end of list */ }
>> +    },
>> +};
>> +
>> +static QemuOptsList runtime_tcp_opts = {
>> +    .name = "vxhs_tcp",
>> +    .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
>> +    .desc = {
>> +        {
>> +            .name = VXHS_OPT_HOST,
>> +            .type = QEMU_OPT_STRING,
>> +            .help = "host address (ipv4 addresses)",
>> +        },
>> +        {
>> +            .name = VXHS_OPT_PORT,
>> +            .type = QEMU_OPT_NUMBER,
>> +            .help = "port number on which VxHSD is listening (default 9999)",
>> +            .def_value_str = "9999"
>> +        },
>> +        { /* end of list */ }
>> +    },
>> +};
>> +
>> +/*
>> + * Parse the incoming URI and populate *options with the host information.
>> + * URI syntax has the limitation of supporting only one host info.
>> + * To pass multiple host information, use the JSON syntax.
>> + */
>> +static int vxhs_parse_uri(const char *filename, QDict *options)
>> +{
>> +    URI *uri = NULL;
>> +    char *hoststr, *portstr;
>> +    char *port;
>> +    int ret = 0;
>> +
>> +    trace_vxhs_parse_uri_filename(filename);
>> +    uri = uri_parse(filename);
>> +    if (!uri || !uri->server || !uri->path) {
>> +        uri_free(uri);
>> +        return -EINVAL;
>> +    }
>> +
>> +    hoststr = g_strdup(VXHS_OPT_SERVER".host");
>> +    qdict_put(options, hoststr, qstring_from_str(uri->server));
>> +    g_free(hoststr);
>> +
>> +    portstr = g_strdup(VXHS_OPT_SERVER".port");
>> +    if (uri->port) {
>> +        port = g_strdup_printf("%d", uri->port);
>> +        qdict_put(options, portstr, qstring_from_str(port));
>> +        g_free(port);
>> +    }
>> +    g_free(portstr);
>> +
>> +    if (strstr(uri->path, "vxhs") == NULL) {
>> +        qdict_put(options, "vdisk-id", qstring_from_str(uri->path));
>> +    }
>> +
>> +    trace_vxhs_parse_uri_hostinfo(1, uri->server, uri->port);
>> +    uri_free(uri);
>> +
>> +    return ret;
>> +}
>> +
>> +static void vxhs_parse_filename(const char *filename, QDict *options,
>> +                                Error **errp)
>> +{
>> +    if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
>> +        error_setg(errp, "vdisk-id/server and a file name may not be specified "
>> +                         "at the same time");
>> +        return;
>> +    }
>> +
>> +    if (strstr(filename, "://")) {
>> +        int ret = vxhs_parse_uri(filename, options);
>> +        if (ret < 0) {
>> +            error_setg(errp, "Invalid URI. URI should be of the form "
>> +                       "  vxhs://<host_ip>:<port>/<vdisk-id>");
>> +        }
>> +    }
>> +}
>> +
>> +static int vxhs_open(BlockDriverState *bs, QDict *options,
>> +                     int bdrv_flags, Error **errp)
>> +{
>> +    BDRVVXHSState *s = bs->opaque;
>> +    void *dev_handlep = NULL;
>> +    QDict *backing_options = NULL;
>> +    QemuOpts *opts, *tcp_opts;
>> +    char *of_vsa_addr = NULL;
>> +    Error *local_err = NULL;
>> +    const char *vdisk_id_opt;
>> +    const char *server_host_opt;
>> +    char *str = NULL;
>> +    int ret = 0;
>> +
>> +    if (lib_init_failed) {
>> +        return -ENODEV;
>> +    }
>
> Since you can't call iio_init() in the bdrv_vxhs_init() function [1],
> instead of the above you can just use a refcnt, and call iio_init when the
> refcnt is 0.
>
>
>> +    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
>> +    qemu_opts_absorb_qdict(opts, options, &local_err);
>> +    if (local_err) {
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    /* vdisk-id is the disk UUID */
>> +    vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
>> +    if (!vdisk_id_opt) {
>> +        error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    /* vdisk-id may contain a leading '/' */
>> +    if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
>> +        error_setg(errp, "vdisk-id cannot be more than %d characters",
>
> You are propagating local_err in the error handler "out:" via
> error_propagate() for all the other cases, but setting errp directly here.
> That will happen to work out, because local_err will be NULL and
> error_propagate() will be a NOOP in that case, but it probably isn't what
> you intended.  You should set &local_err, like in the other error cases.
>
>> +                   UUID_FMT_LEN);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    s->vdisk_guid = g_strdup(vdisk_id_opt);
>> +    trace_vxhs_qemu_init_vdisk(vdisk_id_opt);
>> +
>> +    str = g_strdup_printf(VXHS_OPT_SERVER".");
>> +    qdict_extract_subqdict(options, &backing_options, str);
>> +
>> +    /* Create opts info from runtime_tcp_opts list */
>> +    tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
>> +    qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
>> +    if (local_err) {
>> +        qdict_del(backing_options, str);
>> +        qemu_opts_del(tcp_opts);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
>> +    if (!server_host_opt) {
>> +        error_setg(&local_err, QERR_MISSING_PARAMETER,
>> +                   VXHS_OPT_SERVER"."VXHS_OPT_HOST);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
>> +        error_setg(errp, "server.host cannot be more than %d characters",
>> +                   MAXHOSTNAMELEN);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
>> +
>> +    s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
>> +                                                          VXHS_OPT_PORT),
>> +                                                          NULL, 0);
>> +
>> +    trace_vxhs_qemu_init(s->vdisk_hostinfo.host,
>> +                         s->vdisk_hostinfo.port);
>> +
>> +    qdict_del(backing_options, str);
>> +    qemu_opts_del(tcp_opts);
>> +
>> +    of_vsa_addr = g_strdup_printf("of://%s:%d",
>> +                                s->vdisk_hostinfo.host,
>> +                                s->vdisk_hostinfo.port);
>> +
>> +    /*
>> +     * Open qnio channel to storage agent if not opened before.
>> +     */
>> +    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0);
>> +    if (dev_handlep == NULL) {
>> +        trace_vxhs_qnio_iio_open(of_vsa_addr);
>> +        ret = -ENODEV;
>> +        goto out;
>> +    }
>> +    s->vdisk_hostinfo.dev_handle = dev_handlep;
>> +
>> +out:
>> +    g_free(str);
>> +    g_free(of_vsa_addr);
>> +    QDECREF(backing_options);
>> +    qemu_opts_del(opts);
>> +
>> +    if (ret < 0) {
>> +        error_propagate(errp, local_err);
>> +        g_free(s->vdisk_hostinfo.host);
>> +        g_free(s->vdisk_guid);
>> +        s->vdisk_guid = NULL;
>> +        errno = -ret;
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>> +static const AIOCBInfo vxhs_aiocb_info = {
>> +    .aiocb_size = sizeof(VXHSAIOCB)
>> +};
>> +
>> +/*
>> + * This allocates QEMU-VXHS callback for each IO
>> + * and is passed to QNIO. When QNIO completes the work,
>> + * it will be passed back through the callback.
>> + */
>> +static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
>> +                               QEMUIOVector *qiov, int nb_sectors,
>> +                               BlockCompletionFunc *cb, void *opaque,
>> +                               VDISKAIOCmd iodir)
>> +{
>> +    VXHSAIOCB *acb = NULL;
>> +    BDRVVXHSState *s = bs->opaque;
>> +    size_t size;
>> +    uint64_t offset;
>> +    int iio_flags = 0;
>> +    int ret = 0;
>> +    void *dev_handle = s->vdisk_hostinfo.dev_handle;
>> +
>> +    offset = sector_num * BDRV_SECTOR_SIZE;
>> +    size = nb_sectors * BDRV_SECTOR_SIZE;
>> +    acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
>> +
>> +    /*
>> +     * Initialize VXHSAIOCB.
>> +     */
>> +    acb->err = 0;
>> +    acb->qiov = qiov;
>> +
>> +    iio_flags = IIO_FLAG_ASYNC;
>> +
>> +    switch (iodir) {
>> +    case VDISK_AIO_WRITE:
>> +            ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
>> +                             offset, (uint64_t)size, iio_flags);
>> +            break;
>> +    case VDISK_AIO_READ:
>> +            ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
>> +                            offset, (uint64_t)size, iio_flags);
>> +            break;
>> +    default:
>> +            trace_vxhs_aio_rw_invalid(iodir);
>> +            goto errout;
>> +    }
>> +
>> +    if (ret != 0) {
>> +        trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
>> +                                acb, ret, errno);
>> +        goto errout;
>> +    }
>> +    return &acb->common;
>> +
>> +errout:
>> +    qemu_aio_unref(acb);
>> +    return NULL;
>> +}
>> +
>> +static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
>> +                                   int64_t sector_num, QEMUIOVector *qiov,
>> +                                   int nb_sectors,
>> +                                   BlockCompletionFunc *cb, void *opaque)
>> +{
>> +    return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
>> +                       opaque, VDISK_AIO_READ);
>> +}
>> +
>> +static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
>> +                                   int64_t sector_num, QEMUIOVector *qiov,
>> +                                   int nb_sectors,
>> +                                   BlockCompletionFunc *cb, void *opaque)
>> +{
>> +    return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
>> +                       cb, opaque, VDISK_AIO_WRITE);
>> +}
>> +
>> +static void vxhs_close(BlockDriverState *bs)
>> +{
>> +    BDRVVXHSState *s = bs->opaque;
>> +
>> +    trace_vxhs_close(s->vdisk_guid);
>> +
>> +    g_free(s->vdisk_guid);
>> +    s->vdisk_guid = NULL;
>> +
>> +    /*
>> +     * Close vDisk device
>> +     */
>> +    if (s->vdisk_hostinfo.dev_handle) {
>> +        iio_close(s->vdisk_hostinfo.dev_handle);
>> +        s->vdisk_hostinfo.dev_handle = NULL;
>> +    }
>> +
>> +    /*
>> +     * Free the dynamically allocated host string
>> +     */
>> +    g_free(s->vdisk_hostinfo.host);
>> +    s->vdisk_hostinfo.host = NULL;
>> +    s->vdisk_hostinfo.port = 0;
>
> If you use a static vxhs iio refcnt, you can decrement it here and call
> iio_fini (which is now currently never called) to free resources.
>
>
>> +}
>> +
>> +static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
>> +{
>> +    int64_t vdisk_size = -1;
>> +    int ret = 0;
>> +    void *dev_handle = s->vdisk_hostinfo.dev_handle;
>> +
>> +    ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
>> +    if (ret < 0) {
>> +        trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
>> +        return -EIO;
>> +    }
>> +
>> +    trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
>> +    return vdisk_size;
>> +}
>> +
>> +/*
>> + * Returns the size of vDisk in bytes. This is required
>> + * by QEMU block upper block layer so that it is visible
>> + * to guest.
>> + */
>> +static int64_t vxhs_getlength(BlockDriverState *bs)
>> +{
>> +    BDRVVXHSState *s = bs->opaque;
>> +    int64_t vdisk_size;
>> +
>> +    vdisk_size = vxhs_get_vdisk_stat(s);
>> +    if (vdisk_size < 0) {
>> +        return -EIO;
>> +    }
>> +
>> +    return vdisk_size;
>> +}
>> +
>> +static BlockDriver bdrv_vxhs = {
>> +    .format_name                  = "vxhs",
>> +    .protocol_name                = "vxhs",
>> +    .instance_size                = sizeof(BDRVVXHSState),
>> +    .bdrv_file_open               = vxhs_open,
>> +    .bdrv_parse_filename          = vxhs_parse_filename,
>> +    .bdrv_close                   = vxhs_close,
>> +    .bdrv_getlength               = vxhs_getlength,
>> +    .bdrv_aio_readv               = vxhs_aio_readv,
>> +    .bdrv_aio_writev              = vxhs_aio_writev,
>> +};
>> +
>> +static void bdrv_vxhs_init(void)
>> +{
>> +    char out[37];
>> +
>> +    if (qemu_uuid_is_null(&qemu_uuid)) {
>> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
>> +    } else {
>> +        qemu_uuid_unparse(&qemu_uuid, out);
>> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
>> +    }
>> +
>
> [1]
>
> Can you explain what is going on here with the qemu_uuid check?
>
>
> You also can't do this here.  This init function is just to register the
> driver (e.g. populate the BlockDriver list).  You shouldn't be doing
> anything other than the bdrv_register() call here.
>
> Since you want to run this iio_init only once, I would recommend doing it in
> the vxhs_open() call, and using a ref counter.  That way, you can also call
> iio_fini() to finish releasing resources once the last device is closed.
>
> This was actually a suggestion I had before, which you then incorporated
> into v6, but it appears all the refcnt code has gone away for v7/v8.
>
>
>> +    bdrv_register(&bdrv_vxhs);
>> +}
>> +
>> +block_init(bdrv_vxhs_init);
>> diff --git a/configure b/configure
>> index 6325339..c3ccf02 100755
>> --- a/configure
>> +++ b/configure
>> @@ -321,6 +321,7 @@ numa=""
>>  tcmalloc="no"
>>  jemalloc="no"
>>  replication="yes"
>> +vxhs=""
>>
>>  # parse CC options first
>>  for opt do
>> @@ -1170,6 +1171,10 @@ for opt do
>>    ;;
>>    --enable-replication) replication="yes"
>>    ;;
>> +  --disable-vxhs) vxhs="no"
>> +  ;;
>> +  --enable-vxhs) vxhs="yes"
>> +  ;;
>>    *)
>>        echo "ERROR: unknown option $opt"
>>        echo "Try '$0 --help' for more information"
>> @@ -1403,6 +1408,7 @@ disabled with --disable-FEATURE, default is enabled if available:
>>    tcmalloc        tcmalloc support
>>    jemalloc        jemalloc support
>>    replication     replication support
>> +  vxhs            Veritas HyperScale vDisk backend support
>>
>>  NOTE: The object files are built at the place where configure is launched
>>  EOF
>> @@ -4748,6 +4754,34 @@ if test "$modules" = "yes" && test "$LD_REL_FLAGS" = ""; then
>>  fi
>>
>>  ##########################################
>> +# Veritas HyperScale block driver VxHS
>> +# Check if libvxhs is installed
>> +
>> +if test "$vxhs" != "no" ; then
>> +  cat > $TMPC <<EOF
>> +#include <stdint.h>
>> +#include <qnio/qnio_api.h>
>> +
>> +#define VXHS_UUID "12345678-1234-1234-1234-123456789012"
>> +void *vxhs_callback;
>> +
>> +int main(void) {
>> +    iio_init(QNIO_VERSION, vxhs_callback, VXHS_UUID);
>> +    return 0;
>> +}
>> +EOF
>> +  vxhs_libs="-lvxhs -lssl"
>> +  if compile_prog "" "$vxhs_libs" ; then
>> +    vxhs=yes
>> +  else
>> +    if test "$vxhs" = "yes" ; then
>> +      feature_not_found "vxhs block device" "Install libvxhs See github"
>> +    fi
>> +    vxhs=no
>> +  fi
>> +fi
>> +
>> +##########################################
>>  # End of CC checks
>>  # After here, no more $cc or $ld runs
>>
>> @@ -5114,6 +5148,7 @@ echo "tcmalloc support  $tcmalloc"
>>  echo "jemalloc support  $jemalloc"
>>  echo "avx2 optimization $avx2_opt"
>>  echo "replication support $replication"
>> +echo "VxHS block device $vxhs"
>>
>>  if test "$sdl_too_old" = "yes"; then
>>  echo "-> Your SDL version is too old - please upgrade to have SDL support"
>> @@ -5729,6 +5764,12 @@ if test "$pthread_setname_np" = "yes" ; then
>>    echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak
>>  fi
>>
>> +if test "$vxhs" = "yes" ; then
>> +  echo "CONFIG_VXHS=y" >> $config_host_mak
>> +  echo "VXHS_CFLAGS=$vxhs_cflags" >> $config_host_mak
>> +  echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
>> +fi
>> +
>>  if test "$tcg_interpreter" = "yes"; then
>>    QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
>>  elif test "$ARCH" = "sparc64" ; then
>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index 932f5bb..f37df56 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -2110,6 +2110,7 @@
>>  # @nfs: Since 2.8
>>  # @replication: Since 2.8
>>  # @ssh: Since 2.8
>> +# @vxhs: Since 2.9
>>  #
>>  # Since: 2.0
>>  ##
>> @@ -2119,7 +2120,7 @@
>>              'host_device', 'http', 'https', 'luks', 'nbd', 'nfs', 'null-aio',
>>              'null-co', 'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw',
>>              'replication', 'ssh', 'vdi', 'vhdx', 'vmdk', 'vpc',
>> -            'vvfat' ] }
>> +            'vvfat','vxhs' ] }
>>
>>  ##
>>  # @BlockdevOptionsFile:
>> @@ -2744,6 +2745,20 @@
>>    'data': { '*offset': 'int', '*size': 'int' } }
>>
>>  ##
>> +# @BlockdevOptionsVxHS:
>> +#
>> +# Driver specific block device options for VxHS
>> +#
>> +# @vdisk-id:    UUID of VxHS volume
>> +# @server:      vxhs server IP, port
>> +#
>> +# Since: 2.9
>> +##
>> +{ 'struct': 'BlockdevOptionsVxHS',
>> +  'data': { 'vdisk-id': 'str',
>> +            'server': 'InetSocketAddress' } }
>> +
>> +##
>>  # @BlockdevOptions:
>>  #
>>  # Options for creating a block device.  Many options are available for all
>> @@ -2806,7 +2821,8 @@
>>        'vhdx':       'BlockdevOptionsGenericFormat',
>>        'vmdk':       'BlockdevOptionsGenericCOWFormat',
>>        'vpc':        'BlockdevOptionsGenericFormat',
>> -      'vvfat':      'BlockdevOptionsVVFAT'
>> +      'vvfat':      'BlockdevOptionsVVFAT',
>> +      'vxhs':       'BlockdevOptionsVxHS'
>>    } }
>>
>>  ##
>> --
>> 1.8.3.1
>>

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09  9:24   ` ashish mittal
@ 2017-02-09 14:32     ` Jeff Cody
  2017-02-09 16:14       ` ashish mittal
  2017-02-14 20:51     ` Jeff Cody
  1 sibling, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-09 14:32 UTC (permalink / raw)
  To: ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
> >> From: Ashish Mittal <ashish.mittal@veritas.com>
> >>
> >> Source code for the qnio library that this code loads can be downloaded from:
> >> https://github.com/VeritasHyperScale/libqnio.git
> >>
> >> Sample command line using JSON syntax:
> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
> >> -msg timestamp=on
> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
> >> "server":{"host":"172.172.17.4","port":"9999"}}'
> >>
> >> Sample command line using URI syntax:
> >> qemu-img convert -f raw -O raw -n
> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
> >>
> >
> > I don't know if I am using the qnio_server test server correctly or not, but
> > when I run qemu-io from the command line I get an i/o error.  When I run the
> > qemu-iotests, I get a segfault.
> >
> > Were you able to run qemu-iotests with these patches?
> >
> > Here is how I am invoking qnio_server:
> >
> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
> >
> >
> 
> I ran full qemu-iotests and qemu-io manually with the test server on
> version 7 patches. Ran qemu-io manually with the test server on
> version 8, but the libvxhs code is undergoing a lot of checkins. Will
> test again tomorrow and get back.
>

Does my invocation above look correct, for running the qemu-iotests?

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09 14:32     ` Jeff Cody
@ 2017-02-09 16:14       ` ashish mittal
  2017-02-09 16:50         ` Jeff Cody
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-09 16:14 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 9, 2017 at 6:32 AM, Jeff Cody <jcody@redhat.com> wrote:
> On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>> >>
>> >> Source code for the qnio library that this code loads can be downloaded from:
>> >> https://github.com/VeritasHyperScale/libqnio.git
>> >>
>> >> Sample command line using JSON syntax:
>> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>> >> -msg timestamp=on
>> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>> >>
>> >> Sample command line using URI syntax:
>> >> qemu-img convert -f raw -O raw -n
>> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>> >>
>> >
>> > I don't know if I am using the qnio_server test server correctly or not, but
>> > when I run qemu-io from the command line I get an i/o error.  When I run the
>> > qemu-iotests, I get a segfault.
>> >
>> > Were you able to run qemu-iotests with these patches?
>> >
>> > Here is how I am invoking qnio_server:
>> >
>> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
>> >
>> >
>>
>> I ran full qemu-iotests and qemu-io manually with the test server on
>> version 7 patches. Ran qemu-io manually with the test server on
>> version 8, but the libvxhs code is undergoing a lot of checkins. Will
>> test again tomorrow and get back.
>>
>
> Does my invocation above look correct, for running the qemu-iotests?

qemu-iotest starts the server internally. The server does not have to
be started explicitly before running qemu-iotest. The server must not
be running before you begin the test  because then the tests would
find port 9999 busy.
Running make install on libvxhs copies the test server to the location
where the qemu-iotests expect to find it.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09 16:14       ` ashish mittal
@ 2017-02-09 16:50         ` Jeff Cody
  2017-02-09 18:08           ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-09 16:50 UTC (permalink / raw)
  To: ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 09, 2017 at 08:14:38AM -0800, ashish mittal wrote:
> On Thu, Feb 9, 2017 at 6:32 AM, Jeff Cody <jcody@redhat.com> wrote:
> > On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
> >> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
> >> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
> >> >> From: Ashish Mittal <ashish.mittal@veritas.com>
> >> >>
> >> >> Source code for the qnio library that this code loads can be downloaded from:
> >> >> https://github.com/VeritasHyperScale/libqnio.git
> >> >>
> >> >> Sample command line using JSON syntax:
> >> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
> >> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
> >> >> -msg timestamp=on
> >> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
> >> >> "server":{"host":"172.172.17.4","port":"9999"}}'
> >> >>
> >> >> Sample command line using URI syntax:
> >> >> qemu-img convert -f raw -O raw -n
> >> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
> >> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
> >> >>
> >> >
> >> > I don't know if I am using the qnio_server test server correctly or not, but
> >> > when I run qemu-io from the command line I get an i/o error.  When I run the
> >> > qemu-iotests, I get a segfault.
> >> >
> >> > Were you able to run qemu-iotests with these patches?
> >> >
> >> > Here is how I am invoking qnio_server:
> >> >
> >> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
> >> >
> >> >
> >>
> >> I ran full qemu-iotests and qemu-io manually with the test server on
> >> version 7 patches. Ran qemu-io manually with the test server on
> >> version 8, but the libvxhs code is undergoing a lot of checkins. Will
> >> test again tomorrow and get back.
> >>
> >
> > Does my invocation above look correct, for running the qemu-iotests?
> 
> qemu-iotest starts the server internally. The server does not have to
> be started explicitly before running qemu-iotest. The server must not
> be running before you begin the test  because then the tests would
> find port 9999 busy.
> Running make install on libvxhs copies the test server to the location
> where the qemu-iotests expect to find it.


OK, thanks.  I tried that too, and I also tried against the branch
"ashish_securify_changes" for libqnio.  I still have qemu-iotests giving me
a segfault.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09 16:50         ` Jeff Cody
@ 2017-02-09 18:08           ` ashish mittal
  2017-02-09 18:45             ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-09 18:08 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 9, 2017 at 8:50 AM, Jeff Cody <jcody@redhat.com> wrote:
> On Thu, Feb 09, 2017 at 08:14:38AM -0800, ashish mittal wrote:
>> On Thu, Feb 9, 2017 at 6:32 AM, Jeff Cody <jcody@redhat.com> wrote:
>> > On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>> >> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>> >> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>> >> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>> >> >>
>> >> >> Source code for the qnio library that this code loads can be downloaded from:
>> >> >> https://github.com/VeritasHyperScale/libqnio.git
>> >> >>
>> >> >> Sample command line using JSON syntax:
>> >> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>> >> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>> >> >> -msg timestamp=on
>> >> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>> >> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>> >> >>
>> >> >> Sample command line using URI syntax:
>> >> >> qemu-img convert -f raw -O raw -n
>> >> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>> >> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>> >> >>
>> >> >
>> >> > I don't know if I am using the qnio_server test server correctly or not, but
>> >> > when I run qemu-io from the command line I get an i/o error.  When I run the
>> >> > qemu-iotests, I get a segfault.
>> >> >
>> >> > Were you able to run qemu-iotests with these patches?
>> >> >
>> >> > Here is how I am invoking qnio_server:
>> >> >
>> >> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
>> >> >
>> >> >
>> >>
>> >> I ran full qemu-iotests and qemu-io manually with the test server on
>> >> version 7 patches. Ran qemu-io manually with the test server on
>> >> version 8, but the libvxhs code is undergoing a lot of checkins. Will
>> >> test again tomorrow and get back.
>> >>
>> >
>> > Does my invocation above look correct, for running the qemu-iotests?
>>
>> qemu-iotest starts the server internally. The server does not have to
>> be started explicitly before running qemu-iotest. The server must not
>> be running before you begin the test  because then the tests would
>> find port 9999 busy.
>> Running make install on libvxhs copies the test server to the location
>> where the qemu-iotests expect to find it.
>
>
> OK, thanks.  I tried that too, and I also tried against the branch
> "ashish_securify_changes" for libqnio.  I still have qemu-iotests giving me
> a segfault.
>
>

Qemu patch v7 and v8 do not have many changes. I did successfully run
iotests with v7 and libqnio master. I'm guessing there could be
something in the 'securify' library branch that's causing this. I will
rebuild and retest.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09 18:08           ` ashish mittal
@ 2017-02-09 18:45             ` ashish mittal
  2017-02-10  0:27               ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-09 18:45 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 9, 2017 at 10:08 AM, ashish mittal <ashmit602@gmail.com> wrote:
> On Thu, Feb 9, 2017 at 8:50 AM, Jeff Cody <jcody@redhat.com> wrote:
>> On Thu, Feb 09, 2017 at 08:14:38AM -0800, ashish mittal wrote:
>>> On Thu, Feb 9, 2017 at 6:32 AM, Jeff Cody <jcody@redhat.com> wrote:
>>> > On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>>> >> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>>> >> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>>> >> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>>> >> >>
>>> >> >> Source code for the qnio library that this code loads can be downloaded from:
>>> >> >> https://github.com/VeritasHyperScale/libqnio.git
>>> >> >>
>>> >> >> Sample command line using JSON syntax:
>>> >> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>>> >> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>>> >> >> -msg timestamp=on
>>> >> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>>> >> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>>> >> >>
>>> >> >> Sample command line using URI syntax:
>>> >> >> qemu-img convert -f raw -O raw -n
>>> >> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>>> >> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>>> >> >>
>>> >> >
>>> >> > I don't know if I am using the qnio_server test server correctly or not, but
>>> >> > when I run qemu-io from the command line I get an i/o error.  When I run the
>>> >> > qemu-iotests, I get a segfault.
>>> >> >
>>> >> > Were you able to run qemu-iotests with these patches?
>>> >> >
>>> >> > Here is how I am invoking qnio_server:
>>> >> >
>>> >> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
>>> >> >
>>> >> >
>>> >>
>>> >> I ran full qemu-iotests and qemu-io manually with the test server on
>>> >> version 7 patches. Ran qemu-io manually with the test server on
>>> >> version 8, but the libvxhs code is undergoing a lot of checkins. Will
>>> >> test again tomorrow and get back.
>>> >>
>>> >
>>> > Does my invocation above look correct, for running the qemu-iotests?
>>>
>>> qemu-iotest starts the server internally. The server does not have to
>>> be started explicitly before running qemu-iotest. The server must not
>>> be running before you begin the test  because then the tests would
>>> find port 9999 busy.
>>> Running make install on libvxhs copies the test server to the location
>>> where the qemu-iotests expect to find it.
>>
>>
>> OK, thanks.  I tried that too, and I also tried against the branch
>> "ashish_securify_changes" for libqnio.  I still have qemu-iotests giving me
>> a segfault.
>>
>>
>
> Qemu patch v7 and v8 do not have many changes. I did successfully run
> iotests with v7 and libqnio master. I'm guessing there could be
> something in the 'securify' library branch that's causing this. I will
> rebuild and retest.

Confirmed that there is a problem and qemu-iotest is segfaulting. Will
get back with a fix.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09 18:45             ` ashish mittal
@ 2017-02-10  0:27               ` ashish mittal
  2017-02-10  2:18                 ` Jeff Cody
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-10  0:27 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 9, 2017 at 10:45 AM, ashish mittal <ashmit602@gmail.com> wrote:
> On Thu, Feb 9, 2017 at 10:08 AM, ashish mittal <ashmit602@gmail.com> wrote:
>> On Thu, Feb 9, 2017 at 8:50 AM, Jeff Cody <jcody@redhat.com> wrote:
>>> On Thu, Feb 09, 2017 at 08:14:38AM -0800, ashish mittal wrote:
>>>> On Thu, Feb 9, 2017 at 6:32 AM, Jeff Cody <jcody@redhat.com> wrote:
>>>> > On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>>>> >> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>>>> >> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>>>> >> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>>>> >> >>
>>>> >> >> Source code for the qnio library that this code loads can be downloaded from:
>>>> >> >> https://github.com/VeritasHyperScale/libqnio.git
>>>> >> >>
>>>> >> >> Sample command line using JSON syntax:
>>>> >> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>>>> >> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>>>> >> >> -msg timestamp=on
>>>> >> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>>>> >> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>>>> >> >>
>>>> >> >> Sample command line using URI syntax:
>>>> >> >> qemu-img convert -f raw -O raw -n
>>>> >> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>>>> >> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>>>> >> >>
>>>> >> >
>>>> >> > I don't know if I am using the qnio_server test server correctly or not, but
>>>> >> > when I run qemu-io from the command line I get an i/o error.  When I run the
>>>> >> > qemu-iotests, I get a segfault.
>>>> >> >
>>>> >> > Were you able to run qemu-iotests with these patches?
>>>> >> >
>>>> >> > Here is how I am invoking qnio_server:
>>>> >> >
>>>> >> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
>>>> >> >
>>>> >> >
>>>> >>
>>>> >> I ran full qemu-iotests and qemu-io manually with the test server on
>>>> >> version 7 patches. Ran qemu-io manually with the test server on
>>>> >> version 8, but the libvxhs code is undergoing a lot of checkins. Will
>>>> >> test again tomorrow and get back.
>>>> >>
>>>> >
>>>> > Does my invocation above look correct, for running the qemu-iotests?
>>>>
>>>> qemu-iotest starts the server internally. The server does not have to
>>>> be started explicitly before running qemu-iotest. The server must not
>>>> be running before you begin the test  because then the tests would
>>>> find port 9999 busy.
>>>> Running make install on libvxhs copies the test server to the location
>>>> where the qemu-iotests expect to find it.
>>>
>>>
>>> OK, thanks.  I tried that too, and I also tried against the branch
>>> "ashish_securify_changes" for libqnio.  I still have qemu-iotests giving me
>>> a segfault.
>>>
>>>
>>
>> Qemu patch v7 and v8 do not have many changes. I did successfully run
>> iotests with v7 and libqnio master. I'm guessing there could be
>> something in the 'securify' library branch that's causing this. I will
>> rebuild and retest.
>
> Confirmed that there is a problem and qemu-iotest is segfaulting. Will
> get back with a fix.

Checked in some changes to libqnio. Could you please try it again with
the latest 'securify' branch?
Thanks!

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-10  0:27               ` ashish mittal
@ 2017-02-10  2:18                 ` Jeff Cody
  0 siblings, 0 replies; 56+ messages in thread
From: Jeff Cody @ 2017-02-10  2:18 UTC (permalink / raw)
  To: ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 09, 2017 at 04:27:07PM -0800, ashish mittal wrote:
> On Thu, Feb 9, 2017 at 10:45 AM, ashish mittal <ashmit602@gmail.com> wrote:
> > On Thu, Feb 9, 2017 at 10:08 AM, ashish mittal <ashmit602@gmail.com> wrote:
> >> On Thu, Feb 9, 2017 at 8:50 AM, Jeff Cody <jcody@redhat.com> wrote:
> >>> On Thu, Feb 09, 2017 at 08:14:38AM -0800, ashish mittal wrote:
> >>>> On Thu, Feb 9, 2017 at 6:32 AM, Jeff Cody <jcody@redhat.com> wrote:
> >>>> > On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
> >>>> >> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
> >>>> >> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
> >>>> >> >> From: Ashish Mittal <ashish.mittal@veritas.com>
> >>>> >> >>
> >>>> >> >> Source code for the qnio library that this code loads can be downloaded from:
> >>>> >> >> https://github.com/VeritasHyperScale/libqnio.git
> >>>> >> >>
> >>>> >> >> Sample command line using JSON syntax:
> >>>> >> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
> >>>> >> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
> >>>> >> >> -msg timestamp=on
> >>>> >> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
> >>>> >> >> "server":{"host":"172.172.17.4","port":"9999"}}'
> >>>> >> >>
> >>>> >> >> Sample command line using URI syntax:
> >>>> >> >> qemu-img convert -f raw -O raw -n
> >>>> >> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
> >>>> >> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
> >>>> >> >>
> >>>> >> >
> >>>> >> > I don't know if I am using the qnio_server test server correctly or not, but
> >>>> >> > when I run qemu-io from the command line I get an i/o error.  When I run the
> >>>> >> > qemu-iotests, I get a segfault.
> >>>> >> >
> >>>> >> > Were you able to run qemu-iotests with these patches?
> >>>> >> >
> >>>> >> > Here is how I am invoking qnio_server:
> >>>> >> >
> >>>> >> > # qnio_server  -d /home/jcody/work/redhat/upstream/qemu-kvm/tests/qemu-iotests/scratch -v
> >>>> >> >
> >>>> >> >
> >>>> >>
> >>>> >> I ran full qemu-iotests and qemu-io manually with the test server on
> >>>> >> version 7 patches. Ran qemu-io manually with the test server on
> >>>> >> version 8, but the libvxhs code is undergoing a lot of checkins. Will
> >>>> >> test again tomorrow and get back.
> >>>> >>
> >>>> >
> >>>> > Does my invocation above look correct, for running the qemu-iotests?
> >>>>
> >>>> qemu-iotest starts the server internally. The server does not have to
> >>>> be started explicitly before running qemu-iotest. The server must not
> >>>> be running before you begin the test  because then the tests would
> >>>> find port 9999 busy.
> >>>> Running make install on libvxhs copies the test server to the location
> >>>> where the qemu-iotests expect to find it.
> >>>
> >>>
> >>> OK, thanks.  I tried that too, and I also tried against the branch
> >>> "ashish_securify_changes" for libqnio.  I still have qemu-iotests giving me
> >>> a segfault.
> >>>
> >>>
> >>
> >> Qemu patch v7 and v8 do not have many changes. I did successfully run
> >> iotests with v7 and libqnio master. I'm guessing there could be
> >> something in the 'securify' library branch that's causing this. I will
> >> rebuild and retest.
> >
> > Confirmed that there is a problem and qemu-iotest is segfaulting. Will
> > get back with a fix.
> 
> Checked in some changes to libqnio. Could you please try it again with
> the latest 'securify' branch?

Thanks - I just tried it, and can confirm that all 26 tests pass with raw:

# ./check -vxhs -raw

[...]

Passed all 26 tests


-Jeff

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-09  9:24   ` ashish mittal
  2017-02-09 14:32     ` Jeff Cody
@ 2017-02-14 20:51     ` Jeff Cody
  2017-02-14 22:34       ` ashish mittal
  1 sibling, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-14 20:51 UTC (permalink / raw)
  To: ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey

On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
> >> From: Ashish Mittal <ashish.mittal@veritas.com>
> >>
> >> Source code for the qnio library that this code loads can be downloaded from:
> >> https://github.com/VeritasHyperScale/libqnio.git
> >>
> >> Sample command line using JSON syntax:
> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
> >> -msg timestamp=on
> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
> >> "server":{"host":"172.172.17.4","port":"9999"}}'
> >>
> >> Sample command line using URI syntax:
> >> qemu-img convert -f raw -O raw -n
> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
> >>

[...]

> >> +#define VXHS_OPT_FILENAME           "filename"
> >> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
> >> +#define VXHS_OPT_SERVER             "server"
> >> +#define VXHS_OPT_HOST               "host"
> >> +#define VXHS_OPT_PORT               "port"
> >> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
> >
> > What is this?  It is not a valid UUID; is the value significant?
> >
> 
> This value gets passed to libvxhs for binaries like qemu-io, qemu-img
> that do not have an Instance ID. We can use this default ID to control
> access to specific vdisks by these binaries. qemu-kvm will pass the
> actual instance ID, and therefore will not use this default value.
> 
> Will reply to other queries soon.
>

If you are going to call it a UUID, it should adhere to the RFC 4122 spec.
You can easily generate a compliant UUID with uuidgen.  However:

Can you explain more about how you are using this to control access by
qemu-img and qemu-io?  Looking at libqnio, it looks like this is used to
determine at runtime which TLS certs to use based off of a
pathname/filename, which is then how I presume you are controlling access.
See Daniel's email regarding TLS certificates.

[...]

> >> +
> >> +static void bdrv_vxhs_init(void)
> >> +{
> >> +    char out[37];

Additional point: this should be sized as UUID_FMT_LEN + 1, not 37, but I
suspect this code is changing anyways.

> >> +
> >> +    if (qemu_uuid_is_null(&qemu_uuid)) {
> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
> >> +    } else {
> >> +        qemu_uuid_unparse(&qemu_uuid, out);
> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
> >> +    }
> >> +
> >
> > [1]
> >
> > Can you explain what is going on here with the qemu_uuid check?
> >
> >
> > You also can't do this here.  This init function is just to register the
> > driver (e.g. populate the BlockDriver list).  You shouldn't be doing
> > anything other than the bdrv_register() call here.
> >
> > Since you want to run this iio_init only once, I would recommend doing it in
> > the vxhs_open() call, and using a ref counter.  That way, you can also call
> > iio_fini() to finish releasing resources once the last device is closed.
> >
> > This was actually a suggestion I had before, which you then incorporated
> > into v6, but it appears all the refcnt code has gone away for v7/v8.
> >
> >
> >> +    bdrv_register(&bdrv_vxhs);
> >> +}
> >> +

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-14 20:51     ` Jeff Cody
@ 2017-02-14 22:34       ` ashish mittal
  2017-02-15  3:02         ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-14 22:34 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 14, 2017 at 12:51 PM, Jeff Cody <jcody@redhat.com> wrote:
> On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>> >>
>> >> Source code for the qnio library that this code loads can be downloaded from:
>> >> https://github.com/VeritasHyperScale/libqnio.git
>> >>
>> >> Sample command line using JSON syntax:
>> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>> >> -msg timestamp=on
>> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>> >>
>> >> Sample command line using URI syntax:
>> >> qemu-img convert -f raw -O raw -n
>> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>> >>
>
> [...]
>
>> >> +#define VXHS_OPT_FILENAME           "filename"
>> >> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
>> >> +#define VXHS_OPT_SERVER             "server"
>> >> +#define VXHS_OPT_HOST               "host"
>> >> +#define VXHS_OPT_PORT               "port"
>> >> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
>> >
>> > What is this?  It is not a valid UUID; is the value significant?
>> >
>>
>> This value gets passed to libvxhs for binaries like qemu-io, qemu-img
>> that do not have an Instance ID. We can use this default ID to control
>> access to specific vdisks by these binaries. qemu-kvm will pass the
>> actual instance ID, and therefore will not use this default value.
>>
>> Will reply to other queries soon.
>>
>
> If you are going to call it a UUID, it should adhere to the RFC 4122 spec.
> You can easily generate a compliant UUID with uuidgen.  However:
>
> Can you explain more about how you are using this to control access by
> qemu-img and qemu-io?  Looking at libqnio, it looks like this is used to
> determine at runtime which TLS certs to use based off of a
> pathname/filename, which is then how I presume you are controlling access.
> See Daniel's email regarding TLS certificates.
>

(1) The default behavior would be to disallow access to any vdisks by
the non qemu-kvm binaries. qemu-kvm would use the actual instance ID
for authentication.
(2) Depending on the workflow, HyperScale controller can choose to
grant *temporary* access to specific vdisks by qemu-img, qemu-io
binaries (identified by the default VXHS_UUID_DEF above).
(3) This information, described in #2, would be communicated by the
HyperScale controller to the actual proprietary VxHS server (running
on each compute) that does the authentication/SSL.
(4) The HyperScale controller, in this way, can grant/revoke access
for specific vdisks not just to clients with VXHS_UUID_DEF instance
ID, but also the actual VM instances.

> [...]
>
>> >> +
>> >> +static void bdrv_vxhs_init(void)
>> >> +{
>> >> +    char out[37];
>
> Additional point: this should be sized as UUID_FMT_LEN + 1, not 37, but I
> suspect this code is changing anyways.
>
>> >> +
>> >> +    if (qemu_uuid_is_null(&qemu_uuid)) {
>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
>> >> +    } else {
>> >> +        qemu_uuid_unparse(&qemu_uuid, out);
>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
>> >> +    }
>> >> +
>> >
>> > [1]
>> >
>> > Can you explain what is going on here with the qemu_uuid check?
>> >

(1) qemu_uuid_is_null(&qemu_uuid) is true for qemu-io, qemu-img that
do not define a instance ID. We end up using the default VXHS_UUID_DEF
ID for them, and authenticating them as described above.

(2) For the other case 'else', we convert the uuid to a char * using
qemu_uuid_unparse(), and pass the resulting char * uuid in variable
'out' to libvxhs.

>> >
>> > You also can't do this here.  This init function is just to register the
>> > driver (e.g. populate the BlockDriver list).  You shouldn't be doing
>> > anything other than the bdrv_register() call here.
>> >
>> > Since you want to run this iio_init only once, I would recommend doing it in
>> > the vxhs_open() call, and using a ref counter.  That way, you can also call
>> > iio_fini() to finish releasing resources once the last device is closed.
>> >
>> > This was actually a suggestion I had before, which you then incorporated
>> > into v6, but it appears all the refcnt code has gone away for v7/v8.
>> >
>> >
>> >> +    bdrv_register(&bdrv_vxhs);
>> >> +}
>> >> +

Will consider this in the next patch.

Regards,
Ashish

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-14 22:34       ` ashish mittal
@ 2017-02-15  3:02         ` ashish mittal
  2017-02-15  3:54           ` Jeff Cody
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-15  3:02 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 14, 2017 at 2:34 PM, ashish mittal <ashmit602@gmail.com> wrote:
> On Tue, Feb 14, 2017 at 12:51 PM, Jeff Cody <jcody@redhat.com> wrote:
>> On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>>> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>>> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>>> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>>> >>
>>> >> Source code for the qnio library that this code loads can be downloaded from:
>>> >> https://github.com/VeritasHyperScale/libqnio.git
>>> >>
>>> >> Sample command line using JSON syntax:
>>> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>>> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>>> >> -msg timestamp=on
>>> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>>> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>>> >>
>>> >> Sample command line using URI syntax:
>>> >> qemu-img convert -f raw -O raw -n
>>> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>>> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>>> >>
>>
>> [...]
>>
>>> >> +#define VXHS_OPT_FILENAME           "filename"
>>> >> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
>>> >> +#define VXHS_OPT_SERVER             "server"
>>> >> +#define VXHS_OPT_HOST               "host"
>>> >> +#define VXHS_OPT_PORT               "port"
>>> >> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
>>> >
>>> > What is this?  It is not a valid UUID; is the value significant?
>>> >
>>>
>>> This value gets passed to libvxhs for binaries like qemu-io, qemu-img
>>> that do not have an Instance ID. We can use this default ID to control
>>> access to specific vdisks by these binaries. qemu-kvm will pass the
>>> actual instance ID, and therefore will not use this default value.
>>>
>>> Will reply to other queries soon.
>>>
>>
>> If you are going to call it a UUID, it should adhere to the RFC 4122 spec.
>> You can easily generate a compliant UUID with uuidgen.  However:
>>
>> Can you explain more about how you are using this to control access by
>> qemu-img and qemu-io?  Looking at libqnio, it looks like this is used to
>> determine at runtime which TLS certs to use based off of a
>> pathname/filename, which is then how I presume you are controlling access.
>> See Daniel's email regarding TLS certificates.
>>
>
> (1) The default behavior would be to disallow access to any vdisks by
> the non qemu-kvm binaries. qemu-kvm would use the actual instance ID
> for authentication.
> (2) Depending on the workflow, HyperScale controller can choose to
> grant *temporary* access to specific vdisks by qemu-img, qemu-io
> binaries (identified by the default VXHS_UUID_DEF above).
> (3) This information, described in #2, would be communicated by the
> HyperScale controller to the actual proprietary VxHS server (running
> on each compute) that does the authentication/SSL.
> (4) The HyperScale controller, in this way, can grant/revoke access
> for specific vdisks not just to clients with VXHS_UUID_DEF instance
> ID, but also the actual VM instances.
>
>> [...]
>>
>>> >> +
>>> >> +static void bdrv_vxhs_init(void)
>>> >> +{
>>> >> +    char out[37];
>>
>> Additional point: this should be sized as UUID_FMT_LEN + 1, not 37, but I
>> suspect this code is changing anyways.
>>
>>> >> +
>>> >> +    if (qemu_uuid_is_null(&qemu_uuid)) {
>>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
>>> >> +    } else {
>>> >> +        qemu_uuid_unparse(&qemu_uuid, out);
>>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
>>> >> +    }
>>> >> +
>>> >
>>> > [1]
>>> >
>>> > Can you explain what is going on here with the qemu_uuid check?
>>> >
>
> (1) qemu_uuid_is_null(&qemu_uuid) is true for qemu-io, qemu-img that
> do not define a instance ID. We end up using the default VXHS_UUID_DEF
> ID for them, and authenticating them as described above.
>
> (2) For the other case 'else', we convert the uuid to a char * using
> qemu_uuid_unparse(), and pass the resulting char * uuid in variable
> 'out' to libvxhs.
>
>>> >
>>> > You also can't do this here.  This init function is just to register the
>>> > driver (e.g. populate the BlockDriver list).  You shouldn't be doing
>>> > anything other than the bdrv_register() call here.
>>> >
>>> > Since you want to run this iio_init only once, I would recommend doing it in
>>> > the vxhs_open() call, and using a ref counter.  That way, you can also call
>>> > iio_fini() to finish releasing resources once the last device is closed.
>>> >
>>> > This was actually a suggestion I had before, which you then incorporated
>>> > into v6, but it appears all the refcnt code has gone away for v7/v8.
>>> >
>>> >
>>> >> +    bdrv_register(&bdrv_vxhs);
>>> >> +}
>>> >> +
>

Per my understanding, device open and close are serialized, therefore
I would not need to use the refcnt under a lock.
Does the following diff look ok for the refcnt and iio_fini() change?

diff --git a/block/vxhs.c b/block/vxhs.c
index f1b5f1c..d07a461 100644
--- a/block/vxhs.c
+++ b/block/vxhs.c
@@ -27,7 +27,7 @@

 QemuUUID qemu_uuid __attribute__ ((weak));

-static int lib_init_failed;
+static uint32_t refcnt;

 typedef enum {
     VDISK_AIO_READ,
@@ -232,9 +232,24 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     char *str = NULL;
     int ret = 0;

-    if (lib_init_failed) {
-        return -ENODEV;
+    if (refcnt == 0) {
+        char out[UUID_FMT_LEN + 1];
+        if (qemu_uuid_is_null(&qemu_uuid)) {
+            if (iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF))
+                return -ENODEV;
+        } else {
+            qemu_uuid_unparse(&qemu_uuid, out);
+            if (iio_init(QNIO_VERSION, vxhs_iio_callback, out))
+                return -ENODEV;
+        }
     }
+
+    /*
+     * Increment refcnt before actual open.
+     * We will decrement it if there is an error.
+     */
+    refcnt++;
+
     opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
     qemu_opts_absorb_qdict(opts, options, &local_err);
     if (local_err) {
@@ -323,6 +338,13 @@ out:
     qemu_opts_del(opts);

     if (ret < 0) {
+        if (refcnt == 1) {
+            /*
+             * First device open resulted in error.
+             */
+            iio_fini();
+        }
+        refcnt--;
         error_propagate(errp, local_err);
         g_free(s->vdisk_hostinfo.host);
         g_free(s->vdisk_guid);
@@ -428,6 +450,10 @@ static void vxhs_close(BlockDriverState *bs)
         s->vdisk_hostinfo.dev_handle = NULL;
     }

+    if (--refcnt == 0) {
+        iio_fini();
+    }
+
     /*
      * Free the dynamically allocated host string
      */
@@ -484,15 +510,6 @@ static BlockDriver bdrv_vxhs = {

 static void bdrv_vxhs_init(void)
 {
-    char out[37];
-
-    if (qemu_uuid_is_null(&qemu_uuid)) {
-        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback,
VXHS_UUID_DEF);
-    } else {
-        qemu_uuid_unparse(&qemu_uuid, out);
-        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
-    }
-
     bdrv_register(&bdrv_vxhs);
 }

Thanks,
Ashish

> Will consider this in the next patch.
>
> Regards,
> Ashish

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-15  3:02         ` ashish mittal
@ 2017-02-15  3:54           ` Jeff Cody
  2017-02-15 20:34             ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-15  3:54 UTC (permalink / raw)
  To: ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 14, 2017 at 07:02:32PM -0800, ashish mittal wrote:
> On Tue, Feb 14, 2017 at 2:34 PM, ashish mittal <ashmit602@gmail.com> wrote:
> > On Tue, Feb 14, 2017 at 12:51 PM, Jeff Cody <jcody@redhat.com> wrote:
> >> On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
> >>> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
> >>> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
> >>> >> From: Ashish Mittal <ashish.mittal@veritas.com>
> >>> >>
> >>> >> Source code for the qnio library that this code loads can be downloaded from:
> >>> >> https://github.com/VeritasHyperScale/libqnio.git
> >>> >>
> >>> >> Sample command line using JSON syntax:
> >>> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
> >>> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
> >>> >> -msg timestamp=on
> >>> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
> >>> >> "server":{"host":"172.172.17.4","port":"9999"}}'
> >>> >>
> >>> >> Sample command line using URI syntax:
> >>> >> qemu-img convert -f raw -O raw -n
> >>> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
> >>> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
> >>> >>
> >>
> >> [...]
> >>
> >>> >> +#define VXHS_OPT_FILENAME           "filename"
> >>> >> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
> >>> >> +#define VXHS_OPT_SERVER             "server"
> >>> >> +#define VXHS_OPT_HOST               "host"
> >>> >> +#define VXHS_OPT_PORT               "port"
> >>> >> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
> >>> >
> >>> > What is this?  It is not a valid UUID; is the value significant?
> >>> >
> >>>
> >>> This value gets passed to libvxhs for binaries like qemu-io, qemu-img
> >>> that do not have an Instance ID. We can use this default ID to control
> >>> access to specific vdisks by these binaries. qemu-kvm will pass the
> >>> actual instance ID, and therefore will not use this default value.
> >>>
> >>> Will reply to other queries soon.
> >>>
> >>
> >> If you are going to call it a UUID, it should adhere to the RFC 4122 spec.
> >> You can easily generate a compliant UUID with uuidgen.  However:
> >>
> >> Can you explain more about how you are using this to control access by
> >> qemu-img and qemu-io?  Looking at libqnio, it looks like this is used to
> >> determine at runtime which TLS certs to use based off of a
> >> pathname/filename, which is then how I presume you are controlling access.
> >> See Daniel's email regarding TLS certificates.
> >>
> >
> > (1) The default behavior would be to disallow access to any vdisks by
> > the non qemu-kvm binaries. qemu-kvm would use the actual instance ID
> > for authentication.
> > (2) Depending on the workflow, HyperScale controller can choose to
> > grant *temporary* access to specific vdisks by qemu-img, qemu-io
> > binaries (identified by the default VXHS_UUID_DEF above).
> > (3) This information, described in #2, would be communicated by the
> > HyperScale controller to the actual proprietary VxHS server (running
> > on each compute) that does the authentication/SSL.
> > (4) The HyperScale controller, in this way, can grant/revoke access
> > for specific vdisks not just to clients with VXHS_UUID_DEF instance
> > ID, but also the actual VM instances.
> >
> >> [...]
> >>
> >>> >> +
> >>> >> +static void bdrv_vxhs_init(void)
> >>> >> +{
> >>> >> +    char out[37];
> >>
> >> Additional point: this should be sized as UUID_FMT_LEN + 1, not 37, but I
> >> suspect this code is changing anyways.
> >>
> >>> >> +
> >>> >> +    if (qemu_uuid_is_null(&qemu_uuid)) {
> >>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
> >>> >> +    } else {
> >>> >> +        qemu_uuid_unparse(&qemu_uuid, out);
> >>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
> >>> >> +    }
> >>> >> +
> >>> >
> >>> > [1]
> >>> >
> >>> > Can you explain what is going on here with the qemu_uuid check?
> >>> >
> >
> > (1) qemu_uuid_is_null(&qemu_uuid) is true for qemu-io, qemu-img that
> > do not define a instance ID. We end up using the default VXHS_UUID_DEF
> > ID for them, and authenticating them as described above.
> >
> > (2) For the other case 'else', we convert the uuid to a char * using
> > qemu_uuid_unparse(), and pass the resulting char * uuid in variable
> > 'out' to libvxhs.
> >
> >>> >
> >>> > You also can't do this here.  This init function is just to register the
> >>> > driver (e.g. populate the BlockDriver list).  You shouldn't be doing
> >>> > anything other than the bdrv_register() call here.
> >>> >
> >>> > Since you want to run this iio_init only once, I would recommend doing it in
> >>> > the vxhs_open() call, and using a ref counter.  That way, you can also call
> >>> > iio_fini() to finish releasing resources once the last device is closed.
> >>> >
> >>> > This was actually a suggestion I had before, which you then incorporated
> >>> > into v6, but it appears all the refcnt code has gone away for v7/v8.
> >>> >
> >>> >
> >>> >> +    bdrv_register(&bdrv_vxhs);
> >>> >> +}
> >>> >> +
> >
> 
> Per my understanding, device open and close are serialized, therefore
> I would not need to use the refcnt under a lock.

Correct.

> Does the following diff look ok for the refcnt and iio_fini() change?
>

Disclaimer, the following was compiled in my mind only.

Create a wrapper for the ref, and initialize automatically when appropriate.
For instance:



/* Only refs after successful init */
int vxhs_init_and_ref() {
    if (vxhs_ref == 0) {
        char out[UUID_FMT_LEN + 1];
        if (qemu_uuid_is_null(&qemu_uuid)) {
            if (iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF))
                return -ENODEV;
        } else {
            qemu_uuid_unparse(&qemu_uuid, out);
            if (iio_init(QNIO_VERSION, vxhs_iio_callback, out))
                return -ENODEV;
        }
    }
    vxhs_ref++;
    return 0;
}


And then another wrapper to unref it, and then call iio_fini() as
appropriate:


void vxhs_unref() {
    if (vxhs_ref && --vxhs_ref == 0) {
        iio_fini();
    }
}

Now whenever you ref or unref the usage counter, everything happens
correctly automatically.

Then the rest of the patch becomes:

> diff --git a/block/vxhs.c b/block/vxhs.c
> index f1b5f1c..d07a461 100644
> --- a/block/vxhs.c
> +++ b/block/vxhs.c
> @@ -27,7 +27,7 @@
> 
>  QemuUUID qemu_uuid __attribute__ ((weak));
> 
> -static int lib_init_failed;
> +static uint32_t refcnt;

Minor nit: I'd call it vxhs_ref (just a preference).

> 
>  typedef enum {
>      VDISK_AIO_READ,
> @@ -232,9 +232,24 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>      char *str = NULL;
>      int ret = 0;
> 
> -    if (lib_init_failed) {
> -        return -ENODEV;


> +    if (refcnt == 0) {
> +        char out[UUID_FMT_LEN + 1];
> +        if (qemu_uuid_is_null(&qemu_uuid)) {
> +            if (iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF))
> +                return -ENODEV;
> +        } else {
> +            qemu_uuid_unparse(&qemu_uuid, out);
> +            if (iio_init(QNIO_VERSION, vxhs_iio_callback, out))
> +                return -ENODEV;
> +        }
> +    }
> +
> +    /*
> +     * Increment refcnt before actual open.
> +     * We will decrement it if there is an error.
> +     */
> +    refcnt++;
> +

This block then just becomes:

      ret = vxhs_init_and_ref();
      if (ret < 0) {
          return ret;
      }


>      opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
>      qemu_opts_absorb_qdict(opts, options, &local_err);
>      if (local_err) {
> @@ -323,6 +338,13 @@ out:
>      qemu_opts_del(opts);
> 
>      if (ret < 0) {
> +        if (refcnt == 1) {
> +            /*
> +             * First device open resulted in error.
> +             */
> +            iio_fini();
> +        }
> +        refcnt--;

This hunk can just be replaced with:

    vxhs_unref();

>          error_propagate(errp, local_err);
>          g_free(s->vdisk_hostinfo.host);
>          g_free(s->vdisk_guid);
> @@ -428,6 +450,10 @@ static void vxhs_close(BlockDriverState *bs)
>          s->vdisk_hostinfo.dev_handle = NULL;
>      }
> 
> +    if (--refcnt == 0) {
> +        iio_fini();
> +    }
> +

Same here:

    vxhs_unref();


>      /*
>       * Free the dynamically allocated host string
>       */
> @@ -484,15 +510,6 @@ static BlockDriver bdrv_vxhs = {
> 
>  static void bdrv_vxhs_init(void)
>  {
> -    char out[37];
> -
> -    if (qemu_uuid_is_null(&qemu_uuid)) {
> -        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback,
> VXHS_UUID_DEF);
> -    } else {
> -        qemu_uuid_unparse(&qemu_uuid, out);
> -        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
> -    }
> -
>      bdrv_register(&bdrv_vxhs);
>  }
> 
> Thanks,
> Ashish
>

-Jeff

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-15  3:54           ` Jeff Cody
@ 2017-02-15 20:34             ` ashish mittal
  0 siblings, 0 replies; 56+ messages in thread
From: ashish mittal @ 2017-02-15 20:34 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

Thanks! Will change accordingly in the next patch.

On Tue, Feb 14, 2017 at 7:54 PM, Jeff Cody <jcody@redhat.com> wrote:
> On Tue, Feb 14, 2017 at 07:02:32PM -0800, ashish mittal wrote:
>> On Tue, Feb 14, 2017 at 2:34 PM, ashish mittal <ashmit602@gmail.com> wrote:
>> > On Tue, Feb 14, 2017 at 12:51 PM, Jeff Cody <jcody@redhat.com> wrote:
>> >> On Thu, Feb 09, 2017 at 01:24:58AM -0800, ashish mittal wrote:
>> >>> On Wed, Feb 8, 2017 at 10:29 PM, Jeff Cody <jcody@redhat.com> wrote:
>> >>> > On Wed, Feb 08, 2017 at 09:23:33PM -0800, Ashish Mittal wrote:
>> >>> >> From: Ashish Mittal <ashish.mittal@veritas.com>
>> >>> >>
>> >>> >> Source code for the qnio library that this code loads can be downloaded from:
>> >>> >> https://github.com/VeritasHyperScale/libqnio.git
>> >>> >>
>> >>> >> Sample command line using JSON syntax:
>> >>> >> ./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
>> >>> >> -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
>> >>> >> -msg timestamp=on
>> >>> >> 'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
>> >>> >> "server":{"host":"172.172.17.4","port":"9999"}}'
>> >>> >>
>> >>> >> Sample command line using URI syntax:
>> >>> >> qemu-img convert -f raw -O raw -n
>> >>> >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
>> >>> >> vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
>> >>> >>
>> >>
>> >> [...]
>> >>
>> >>> >> +#define VXHS_OPT_FILENAME           "filename"
>> >>> >> +#define VXHS_OPT_VDISK_ID           "vdisk-id"
>> >>> >> +#define VXHS_OPT_SERVER             "server"
>> >>> >> +#define VXHS_OPT_HOST               "host"
>> >>> >> +#define VXHS_OPT_PORT               "port"
>> >>> >> +#define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
>> >>> >
>> >>> > What is this?  It is not a valid UUID; is the value significant?
>> >>> >
>> >>>
>> >>> This value gets passed to libvxhs for binaries like qemu-io, qemu-img
>> >>> that do not have an Instance ID. We can use this default ID to control
>> >>> access to specific vdisks by these binaries. qemu-kvm will pass the
>> >>> actual instance ID, and therefore will not use this default value.
>> >>>
>> >>> Will reply to other queries soon.
>> >>>
>> >>
>> >> If you are going to call it a UUID, it should adhere to the RFC 4122 spec.
>> >> You can easily generate a compliant UUID with uuidgen.  However:
>> >>
>> >> Can you explain more about how you are using this to control access by
>> >> qemu-img and qemu-io?  Looking at libqnio, it looks like this is used to
>> >> determine at runtime which TLS certs to use based off of a
>> >> pathname/filename, which is then how I presume you are controlling access.
>> >> See Daniel's email regarding TLS certificates.
>> >>
>> >
>> > (1) The default behavior would be to disallow access to any vdisks by
>> > the non qemu-kvm binaries. qemu-kvm would use the actual instance ID
>> > for authentication.
>> > (2) Depending on the workflow, HyperScale controller can choose to
>> > grant *temporary* access to specific vdisks by qemu-img, qemu-io
>> > binaries (identified by the default VXHS_UUID_DEF above).
>> > (3) This information, described in #2, would be communicated by the
>> > HyperScale controller to the actual proprietary VxHS server (running
>> > on each compute) that does the authentication/SSL.
>> > (4) The HyperScale controller, in this way, can grant/revoke access
>> > for specific vdisks not just to clients with VXHS_UUID_DEF instance
>> > ID, but also the actual VM instances.
>> >
>> >> [...]
>> >>
>> >>> >> +
>> >>> >> +static void bdrv_vxhs_init(void)
>> >>> >> +{
>> >>> >> +    char out[37];
>> >>
>> >> Additional point: this should be sized as UUID_FMT_LEN + 1, not 37, but I
>> >> suspect this code is changing anyways.
>> >>
>> >>> >> +
>> >>> >> +    if (qemu_uuid_is_null(&qemu_uuid)) {
>> >>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF);
>> >>> >> +    } else {
>> >>> >> +        qemu_uuid_unparse(&qemu_uuid, out);
>> >>> >> +        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
>> >>> >> +    }
>> >>> >> +
>> >>> >
>> >>> > [1]
>> >>> >
>> >>> > Can you explain what is going on here with the qemu_uuid check?
>> >>> >
>> >
>> > (1) qemu_uuid_is_null(&qemu_uuid) is true for qemu-io, qemu-img that
>> > do not define a instance ID. We end up using the default VXHS_UUID_DEF
>> > ID for them, and authenticating them as described above.
>> >
>> > (2) For the other case 'else', we convert the uuid to a char * using
>> > qemu_uuid_unparse(), and pass the resulting char * uuid in variable
>> > 'out' to libvxhs.
>> >
>> >>> >
>> >>> > You also can't do this here.  This init function is just to register the
>> >>> > driver (e.g. populate the BlockDriver list).  You shouldn't be doing
>> >>> > anything other than the bdrv_register() call here.
>> >>> >
>> >>> > Since you want to run this iio_init only once, I would recommend doing it in
>> >>> > the vxhs_open() call, and using a ref counter.  That way, you can also call
>> >>> > iio_fini() to finish releasing resources once the last device is closed.
>> >>> >
>> >>> > This was actually a suggestion I had before, which you then incorporated
>> >>> > into v6, but it appears all the refcnt code has gone away for v7/v8.
>> >>> >
>> >>> >
>> >>> >> +    bdrv_register(&bdrv_vxhs);
>> >>> >> +}
>> >>> >> +
>> >
>>
>> Per my understanding, device open and close are serialized, therefore
>> I would not need to use the refcnt under a lock.
>
> Correct.
>
>> Does the following diff look ok for the refcnt and iio_fini() change?
>>
>
> Disclaimer, the following was compiled in my mind only.
>
> Create a wrapper for the ref, and initialize automatically when appropriate.
> For instance:
>
>
>
> /* Only refs after successful init */
> int vxhs_init_and_ref() {
>     if (vxhs_ref == 0) {
>         char out[UUID_FMT_LEN + 1];
>         if (qemu_uuid_is_null(&qemu_uuid)) {
>             if (iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF))
>                 return -ENODEV;
>         } else {
>             qemu_uuid_unparse(&qemu_uuid, out);
>             if (iio_init(QNIO_VERSION, vxhs_iio_callback, out))
>                 return -ENODEV;
>         }
>     }
>     vxhs_ref++;
>     return 0;
> }
>
>
> And then another wrapper to unref it, and then call iio_fini() as
> appropriate:
>
>
> void vxhs_unref() {
>     if (vxhs_ref && --vxhs_ref == 0) {
>         iio_fini();
>     }
> }
>
> Now whenever you ref or unref the usage counter, everything happens
> correctly automatically.
>
> Then the rest of the patch becomes:
>
>> diff --git a/block/vxhs.c b/block/vxhs.c
>> index f1b5f1c..d07a461 100644
>> --- a/block/vxhs.c
>> +++ b/block/vxhs.c
>> @@ -27,7 +27,7 @@
>>
>>  QemuUUID qemu_uuid __attribute__ ((weak));
>>
>> -static int lib_init_failed;
>> +static uint32_t refcnt;
>
> Minor nit: I'd call it vxhs_ref (just a preference).
>
>>
>>  typedef enum {
>>      VDISK_AIO_READ,
>> @@ -232,9 +232,24 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>>      char *str = NULL;
>>      int ret = 0;
>>
>> -    if (lib_init_failed) {
>> -        return -ENODEV;
>
>
>> +    if (refcnt == 0) {
>> +        char out[UUID_FMT_LEN + 1];
>> +        if (qemu_uuid_is_null(&qemu_uuid)) {
>> +            if (iio_init(QNIO_VERSION, vxhs_iio_callback, VXHS_UUID_DEF))
>> +                return -ENODEV;
>> +        } else {
>> +            qemu_uuid_unparse(&qemu_uuid, out);
>> +            if (iio_init(QNIO_VERSION, vxhs_iio_callback, out))
>> +                return -ENODEV;
>> +        }
>> +    }
>> +
>> +    /*
>> +     * Increment refcnt before actual open.
>> +     * We will decrement it if there is an error.
>> +     */
>> +    refcnt++;
>> +
>
> This block then just becomes:
>
>       ret = vxhs_init_and_ref();
>       if (ret < 0) {
>           return ret;
>       }
>
>
>>      opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
>>      qemu_opts_absorb_qdict(opts, options, &local_err);
>>      if (local_err) {
>> @@ -323,6 +338,13 @@ out:
>>      qemu_opts_del(opts);
>>
>>      if (ret < 0) {
>> +        if (refcnt == 1) {
>> +            /*
>> +             * First device open resulted in error.
>> +             */
>> +            iio_fini();
>> +        }
>> +        refcnt--;
>
> This hunk can just be replaced with:
>
>     vxhs_unref();
>
>>          error_propagate(errp, local_err);
>>          g_free(s->vdisk_hostinfo.host);
>>          g_free(s->vdisk_guid);
>> @@ -428,6 +450,10 @@ static void vxhs_close(BlockDriverState *bs)
>>          s->vdisk_hostinfo.dev_handle = NULL;
>>      }
>>
>> +    if (--refcnt == 0) {
>> +        iio_fini();
>> +    }
>> +
>
> Same here:
>
>     vxhs_unref();
>
>
>>      /*
>>       * Free the dynamically allocated host string
>>       */
>> @@ -484,15 +510,6 @@ static BlockDriver bdrv_vxhs = {
>>
>>  static void bdrv_vxhs_init(void)
>>  {
>> -    char out[37];
>> -
>> -    if (qemu_uuid_is_null(&qemu_uuid)) {
>> -        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback,
>> VXHS_UUID_DEF);
>> -    } else {
>> -        qemu_uuid_unparse(&qemu_uuid, out);
>> -        lib_init_failed = iio_init(QNIO_VERSION, vxhs_iio_callback, out);
>> -    }
>> -
>>      bdrv_register(&bdrv_vxhs);
>>  }
>>
>> Thanks,
>> Ashish
>>
>
> -Jeff

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-23  0:03                                             ` ashish mittal
@ 2017-03-27  3:07                                               ` ashish mittal
  0 siblings, 0 replies; 56+ messages in thread
From: ashish mittal @ 2017-03-27  3:07 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Mar 22, 2017 at 5:03 PM, ashish mittal <ashmit602@gmail.com> wrote:
> On Mon, Mar 20, 2017 at 5:55 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>> On Fri, Mar 17, 2017 at 06:44:56PM -0700, ashish mittal wrote:
>>> On Thu, Mar 16, 2017 at 5:29 PM, ashish mittal <ashmit602@gmail.com> wrote:
>>> > On Mon, Mar 13, 2017 at 2:57 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>>> >> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>>> >>> Thanks! There is one more input I need some help with!
>>> >>>
>>> >>> VxHS network library opens a fixed number of connection channels to a
>>> >>> given host, and all the vdisks (that connect to the same host) share
>>> >>> these connection channels.
>>> >>>
>>> >>> Therefore, we need to open secure channels to a specific target host
>>> >>> only once for the first vdisk that connects to that host. All the
>>> >>> other vdisks that connect to the same target host will share the same
>>> >>> set of secure communication channels.
>>> >>>
>>> >>> I hope the above scheme is acceptable?
>>> >>>
>>> >>> If yes, then we have a couple of options to implement this:
>>> >>>
>>> >>> (1) Accept the TLS credentials per vdisk using the previously
>>> >>> discussed --object tls-creds-x509 mechanism. In this case, if more
>>> >>> than one vdisk have the same host info, then we will use only the
>>> >>> first one's creds to set up the secure connection, and ignore the
>>> >>> others. vdisks that connect to different target hosts will use their
>>> >>> individual tls-creds-x509 to set up the secure channels. This is, of
>>> >>> course, not relevant for qemu-img/qemu-io as they can open only one
>>> >>> vdisk at a time.
>>> >>
>>> >> It looks like option 1 here is the way to go. Just report an error if
>>> >> there are multiple creds provided for the same host and they don't
>>> >> match.
>>> >>
>>> >
>>> > I have made changes to implement option 1 in the library (branch
>>> > per_channel_ssl).
>>> > Can you please help review it?
>>> > https://github.com/VeritasHyperScale/libqnio/compare/per_channel_ssl
>>> >
>>> > Here's the changelog:
>>> > (1) Changed code to not use instance UUID for setting up SSL context.
>>> > (2) User is supposed to pass the cacert, client_key and client_cert
>>> >     files to iio_open(). These will be used to set up a per-channel secure SSL
>>> >     connection to the server. All three values are needed to set up a
>>> >     secure connection.
>>> > (3) If the secure channel to a particular host is already open, other
>>> >     block device connections to the same host will have to provide
>>> >     TLS/SSL credentials that match the original one.
>>> > (4) Set default locations for trusted client CA certificates
>>> >      based on user specified cacert file.
>>> >
>>> > NB - I have given steps to test SSL communication (using the supplied
>>> > test client/server programs) in the commit log. I have not tested
>>> > using qemu binary yet. Will run more tests in the days to come.
>>> >
>>> > qemu vxhs patch changes should be pretty straightforward, given that
>>> > we have already discussed how to implement passing --object
>>> > tls-creds-x509 per block device.
>>> >
>>> > Thanks!
>>> >
>>>
>>> Update -
>>> (1) Successfully tested SSL communication using qemu-io and the test server.
>>> (2) Minor changes to per_channel_ssl branch.
>>> (3) Created a pull request.
>>>
>>> Please review per convenience. Thanks!
>>
>> IIUC, on that branch the 'is_secure()' method is still looking for the
>> directory /var/lib/libvxhs/secure to exist on the host. If that is not
>> present, then it appears to be silently ignoring the SSL certs passed
>> in from QEMU.
>>
>> IMHO it should enable TLS when 'cacert' passed to iio_open is not NULL,
>> not relying on a magic directory to exist.
>>
>
> I have made changes per above to the library. Please see commits -
>
> https://github.com/VeritasHyperScale/libqnio/commit/6c3261e9c9bb1350f4433a1ae4fcd98f7692cf39
> https://github.com/VeritasHyperScale/libqnio/commit/502c74278457e6ac86a4ee4ad9102e56ff3be5d4
>
> Commit log: Enable secure mode based on the SSL/TLS args passed in iio_open()
>
> (1) Do not use /var/lib/libvxhs/secure to enable secure SSL mode on
>     the client side.
> (2) Instead, enable SSL mode if the user passes TLS/SSL creds for
>     the block device on the qemu CLI.
>
> Will be posting v10 qemu vxhs patch soon. v10 will work with the
> latest library changes, and will support passing tls-creds-x509 creds
> for every vxhs block device.
>

I have posted v10 patches today. I've had to make one change in
addition to what has been discussed. Basically I cannot use
qcrypto_tls_creds_get_path() because its definition is under a #ifdef
CONFIG_GNUTLS. Therefore my builds were failing whenever "gnutls" was
not configured. I've replaced it as below -


diff --git a/block/vxhs.c b/block/vxhs.c
index 0aa7849..44c0ecd 100644
--- a/block/vxhs.c
+++ b/block/vxhs.c
@@ -19,7 +19,6 @@
 #include "qemu/uuid.h"
 #include "crypto/secret.h"
 #include "crypto/tlscredsx509.h"
-#include "crypto/tlscredspriv.h"

 #define VXHS_OPT_FILENAME           "filename"
 #define VXHS_OPT_VDISK_ID           "vdisk-id"
@@ -288,17 +287,17 @@ static void vxhs_get_tls_creds(const char *id,
char **cacert,
     /*
      * Get the cacert, client_cert and client_key file names.
      */
-    if (qcrypto_tls_creds_get_path(creds, QCRYPTO_TLS_CREDS_X509_CA_CERT,
-                                   true, cacert, errp) < 0 ||
-        qcrypto_tls_creds_get_path(&creds_x509->parent_obj,
-                                   QCRYPTO_TLS_CREDS_X509_CLIENT_CERT,
-                                   false, cert, errp) < 0 ||
-        qcrypto_tls_creds_get_path(&creds_x509->parent_obj,
-                                   QCRYPTO_TLS_CREDS_X509_CLIENT_KEY,
-                                   false, key, errp) < 0) {
-        error_setg(errp,
-                   "Error retrieving information from  TLS object");
+    if (!creds->dir) {
+        error_setg(errp, "TLS object missing 'dir' property value");
+        return;
     }
+
+    *cacert = g_strdup_printf("%s/%s", creds->dir,
+                              QCRYPTO_TLS_CREDS_X509_CA_CERT);
+    *cert = g_strdup_printf("%s/%s", creds->dir,
+                            QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
+    *key = g_strdup_printf("%s/%s", creds->dir,
+                           QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);
 }

 static int vxhs_open(BlockDriverState *bs, QDict *options,

Regards,
Ashish

>
>> Regards,
>> Daniel
>> --
>> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
>> |: http://libvirt.org              -o-             http://virt-manager.org :|
>> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-20 12:55                                           ` Daniel P. Berrange
@ 2017-03-23  0:03                                             ` ashish mittal
  2017-03-27  3:07                                               ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-03-23  0:03 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Mon, Mar 20, 2017 at 5:55 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Fri, Mar 17, 2017 at 06:44:56PM -0700, ashish mittal wrote:
>> On Thu, Mar 16, 2017 at 5:29 PM, ashish mittal <ashmit602@gmail.com> wrote:
>> > On Mon, Mar 13, 2017 at 2:57 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>> >> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>> >>> Thanks! There is one more input I need some help with!
>> >>>
>> >>> VxHS network library opens a fixed number of connection channels to a
>> >>> given host, and all the vdisks (that connect to the same host) share
>> >>> these connection channels.
>> >>>
>> >>> Therefore, we need to open secure channels to a specific target host
>> >>> only once for the first vdisk that connects to that host. All the
>> >>> other vdisks that connect to the same target host will share the same
>> >>> set of secure communication channels.
>> >>>
>> >>> I hope the above scheme is acceptable?
>> >>>
>> >>> If yes, then we have a couple of options to implement this:
>> >>>
>> >>> (1) Accept the TLS credentials per vdisk using the previously
>> >>> discussed --object tls-creds-x509 mechanism. In this case, if more
>> >>> than one vdisk have the same host info, then we will use only the
>> >>> first one's creds to set up the secure connection, and ignore the
>> >>> others. vdisks that connect to different target hosts will use their
>> >>> individual tls-creds-x509 to set up the secure channels. This is, of
>> >>> course, not relevant for qemu-img/qemu-io as they can open only one
>> >>> vdisk at a time.
>> >>
>> >> It looks like option 1 here is the way to go. Just report an error if
>> >> there are multiple creds provided for the same host and they don't
>> >> match.
>> >>
>> >
>> > I have made changes to implement option 1 in the library (branch
>> > per_channel_ssl).
>> > Can you please help review it?
>> > https://github.com/VeritasHyperScale/libqnio/compare/per_channel_ssl
>> >
>> > Here's the changelog:
>> > (1) Changed code to not use instance UUID for setting up SSL context.
>> > (2) User is supposed to pass the cacert, client_key and client_cert
>> >     files to iio_open(). These will be used to set up a per-channel secure SSL
>> >     connection to the server. All three values are needed to set up a
>> >     secure connection.
>> > (3) If the secure channel to a particular host is already open, other
>> >     block device connections to the same host will have to provide
>> >     TLS/SSL credentials that match the original one.
>> > (4) Set default locations for trusted client CA certificates
>> >      based on user specified cacert file.
>> >
>> > NB - I have given steps to test SSL communication (using the supplied
>> > test client/server programs) in the commit log. I have not tested
>> > using qemu binary yet. Will run more tests in the days to come.
>> >
>> > qemu vxhs patch changes should be pretty straightforward, given that
>> > we have already discussed how to implement passing --object
>> > tls-creds-x509 per block device.
>> >
>> > Thanks!
>> >
>>
>> Update -
>> (1) Successfully tested SSL communication using qemu-io and the test server.
>> (2) Minor changes to per_channel_ssl branch.
>> (3) Created a pull request.
>>
>> Please review per convenience. Thanks!
>
> IIUC, on that branch the 'is_secure()' method is still looking for the
> directory /var/lib/libvxhs/secure to exist on the host. If that is not
> present, then it appears to be silently ignoring the SSL certs passed
> in from QEMU.
>
> IMHO it should enable TLS when 'cacert' passed to iio_open is not NULL,
> not relying on a magic directory to exist.
>

I have made changes per above to the library. Please see commits -

https://github.com/VeritasHyperScale/libqnio/commit/6c3261e9c9bb1350f4433a1ae4fcd98f7692cf39
https://github.com/VeritasHyperScale/libqnio/commit/502c74278457e6ac86a4ee4ad9102e56ff3be5d4

Commit log: Enable secure mode based on the SSL/TLS args passed in iio_open()

(1) Do not use /var/lib/libvxhs/secure to enable secure SSL mode on
    the client side.
(2) Instead, enable SSL mode if the user passes TLS/SSL creds for
    the block device on the qemu CLI.

Will be posting v10 qemu vxhs patch soon. v10 will work with the
latest library changes, and will support passing tls-creds-x509 creds
for every vxhs block device.


> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-18  1:44                                         ` ashish mittal
@ 2017-03-20 12:55                                           ` Daniel P. Berrange
  2017-03-23  0:03                                             ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-20 12:55 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Fri, Mar 17, 2017 at 06:44:56PM -0700, ashish mittal wrote:
> On Thu, Mar 16, 2017 at 5:29 PM, ashish mittal <ashmit602@gmail.com> wrote:
> > On Mon, Mar 13, 2017 at 2:57 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> >> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
> >>> Thanks! There is one more input I need some help with!
> >>>
> >>> VxHS network library opens a fixed number of connection channels to a
> >>> given host, and all the vdisks (that connect to the same host) share
> >>> these connection channels.
> >>>
> >>> Therefore, we need to open secure channels to a specific target host
> >>> only once for the first vdisk that connects to that host. All the
> >>> other vdisks that connect to the same target host will share the same
> >>> set of secure communication channels.
> >>>
> >>> I hope the above scheme is acceptable?
> >>>
> >>> If yes, then we have a couple of options to implement this:
> >>>
> >>> (1) Accept the TLS credentials per vdisk using the previously
> >>> discussed --object tls-creds-x509 mechanism. In this case, if more
> >>> than one vdisk have the same host info, then we will use only the
> >>> first one's creds to set up the secure connection, and ignore the
> >>> others. vdisks that connect to different target hosts will use their
> >>> individual tls-creds-x509 to set up the secure channels. This is, of
> >>> course, not relevant for qemu-img/qemu-io as they can open only one
> >>> vdisk at a time.
> >>
> >> It looks like option 1 here is the way to go. Just report an error if
> >> there are multiple creds provided for the same host and they don't
> >> match.
> >>
> >
> > I have made changes to implement option 1 in the library (branch
> > per_channel_ssl).
> > Can you please help review it?
> > https://github.com/VeritasHyperScale/libqnio/compare/per_channel_ssl
> >
> > Here's the changelog:
> > (1) Changed code to not use instance UUID for setting up SSL context.
> > (2) User is supposed to pass the cacert, client_key and client_cert
> >     files to iio_open(). These will be used to set up a per-channel secure SSL
> >     connection to the server. All three values are needed to set up a
> >     secure connection.
> > (3) If the secure channel to a particular host is already open, other
> >     block device connections to the same host will have to provide
> >     TLS/SSL credentials that match the original one.
> > (4) Set default locations for trusted client CA certificates
> >      based on user specified cacert file.
> >
> > NB - I have given steps to test SSL communication (using the supplied
> > test client/server programs) in the commit log. I have not tested
> > using qemu binary yet. Will run more tests in the days to come.
> >
> > qemu vxhs patch changes should be pretty straightforward, given that
> > we have already discussed how to implement passing --object
> > tls-creds-x509 per block device.
> >
> > Thanks!
> >
> 
> Update -
> (1) Successfully tested SSL communication using qemu-io and the test server.
> (2) Minor changes to per_channel_ssl branch.
> (3) Created a pull request.
> 
> Please review per convenience. Thanks!

IIUC, on that branch the 'is_secure()' method is still looking for the
directory /var/lib/libvxhs/secure to exist on the host. If that is not
present, then it appears to be silently ignoring the SSL certs passed
in from QEMU.

IMHO it should enable TLS when 'cacert' passed to iio_open is not NULL,
not relying on a magic directory to exist.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-17  0:29                                       ` ashish mittal
@ 2017-03-18  1:44                                         ` ashish mittal
  2017-03-20 12:55                                           ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-03-18  1:44 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Thu, Mar 16, 2017 at 5:29 PM, ashish mittal <ashmit602@gmail.com> wrote:
> On Mon, Mar 13, 2017 at 2:57 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>>> Thanks! There is one more input I need some help with!
>>>
>>> VxHS network library opens a fixed number of connection channels to a
>>> given host, and all the vdisks (that connect to the same host) share
>>> these connection channels.
>>>
>>> Therefore, we need to open secure channels to a specific target host
>>> only once for the first vdisk that connects to that host. All the
>>> other vdisks that connect to the same target host will share the same
>>> set of secure communication channels.
>>>
>>> I hope the above scheme is acceptable?
>>>
>>> If yes, then we have a couple of options to implement this:
>>>
>>> (1) Accept the TLS credentials per vdisk using the previously
>>> discussed --object tls-creds-x509 mechanism. In this case, if more
>>> than one vdisk have the same host info, then we will use only the
>>> first one's creds to set up the secure connection, and ignore the
>>> others. vdisks that connect to different target hosts will use their
>>> individual tls-creds-x509 to set up the secure channels. This is, of
>>> course, not relevant for qemu-img/qemu-io as they can open only one
>>> vdisk at a time.
>>
>> It looks like option 1 here is the way to go. Just report an error if
>> there are multiple creds provided for the same host and they don't
>> match.
>>
>
> I have made changes to implement option 1 in the library (branch
> per_channel_ssl).
> Can you please help review it?
> https://github.com/VeritasHyperScale/libqnio/compare/per_channel_ssl
>
> Here's the changelog:
> (1) Changed code to not use instance UUID for setting up SSL context.
> (2) User is supposed to pass the cacert, client_key and client_cert
>     files to iio_open(). These will be used to set up a per-channel secure SSL
>     connection to the server. All three values are needed to set up a
>     secure connection.
> (3) If the secure channel to a particular host is already open, other
>     block device connections to the same host will have to provide
>     TLS/SSL credentials that match the original one.
> (4) Set default locations for trusted client CA certificates
>      based on user specified cacert file.
>
> NB - I have given steps to test SSL communication (using the supplied
> test client/server programs) in the commit log. I have not tested
> using qemu binary yet. Will run more tests in the days to come.
>
> qemu vxhs patch changes should be pretty straightforward, given that
> we have already discussed how to implement passing --object
> tls-creds-x509 per block device.
>
> Thanks!
>

Update -
(1) Successfully tested SSL communication using qemu-io and the test server.
(2) Minor changes to per_channel_ssl branch.
(3) Created a pull request.

Please review per convenience. Thanks!

>>>
>>> (2) Instead of having a per-vdisk --object tls-creds-x509, have a
>>> single such argument on the command line for vxhs block device code to
>>> consume - if that is possible! One way to achieve this could be the
>>> user/password authentication we discussed earlier, which we could use
>>> to pass the directory where cert/keys are kept.
>>>
>>> (3) Use the instance UUID, when available, to lookup the cert files
>>> per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
>>> mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
>>> The cert/key files are anyway protected by file permissions in either
>>> case, so I guess there is no additional security provided by either
>>> method.
>>
>> Regards,
>> Daniel
>> --
>> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
>> |: http://libvirt.org              -o-             http://virt-manager.org :|
>> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-13  9:57                                     ` Daniel P. Berrange
@ 2017-03-17  0:29                                       ` ashish mittal
  2017-03-18  1:44                                         ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-03-17  0:29 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Mon, Mar 13, 2017 at 2:57 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>> Thanks! There is one more input I need some help with!
>>
>> VxHS network library opens a fixed number of connection channels to a
>> given host, and all the vdisks (that connect to the same host) share
>> these connection channels.
>>
>> Therefore, we need to open secure channels to a specific target host
>> only once for the first vdisk that connects to that host. All the
>> other vdisks that connect to the same target host will share the same
>> set of secure communication channels.
>>
>> I hope the above scheme is acceptable?
>>
>> If yes, then we have a couple of options to implement this:
>>
>> (1) Accept the TLS credentials per vdisk using the previously
>> discussed --object tls-creds-x509 mechanism. In this case, if more
>> than one vdisk have the same host info, then we will use only the
>> first one's creds to set up the secure connection, and ignore the
>> others. vdisks that connect to different target hosts will use their
>> individual tls-creds-x509 to set up the secure channels. This is, of
>> course, not relevant for qemu-img/qemu-io as they can open only one
>> vdisk at a time.
>
> It looks like option 1 here is the way to go. Just report an error if
> there are multiple creds provided for the same host and they don't
> match.
>

I have made changes to implement option 1 in the library (branch
per_channel_ssl).
Can you please help review it?
https://github.com/VeritasHyperScale/libqnio/compare/per_channel_ssl

Here's the changelog:
(1) Changed code to not use instance UUID for setting up SSL context.
(2) User is supposed to pass the cacert, client_key and client_cert
    files to iio_open(). These will be used to set up a per-channel secure SSL
    connection to the server. All three values are needed to set up a
    secure connection.
(3) If the secure channel to a particular host is already open, other
    block device connections to the same host will have to provide
    TLS/SSL credentials that match the original one.
(4) Set default locations for trusted client CA certificates
     based on user specified cacert file.

NB - I have given steps to test SSL communication (using the supplied
test client/server programs) in the commit log. I have not tested
using qemu binary yet. Will run more tests in the days to come.

qemu vxhs patch changes should be pretty straightforward, given that
we have already discussed how to implement passing --object
tls-creds-x509 per block device.

Thanks!

>>
>> (2) Instead of having a per-vdisk --object tls-creds-x509, have a
>> single such argument on the command line for vxhs block device code to
>> consume - if that is possible! One way to achieve this could be the
>> user/password authentication we discussed earlier, which we could use
>> to pass the directory where cert/keys are kept.
>>
>> (3) Use the instance UUID, when available, to lookup the cert files
>> per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
>> mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
>> The cert/key files are anyway protected by file permissions in either
>> case, so I guess there is no additional security provided by either
>> method.
>
> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-08  1:27                                   ` ashish mittal
  2017-03-08  9:13                                     ` Daniel P. Berrange
@ 2017-03-13  9:57                                     ` Daniel P. Berrange
  2017-03-17  0:29                                       ` ashish mittal
  1 sibling, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-13  9:57 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
> Thanks! There is one more input I need some help with!
> 
> VxHS network library opens a fixed number of connection channels to a
> given host, and all the vdisks (that connect to the same host) share
> these connection channels.
> 
> Therefore, we need to open secure channels to a specific target host
> only once for the first vdisk that connects to that host. All the
> other vdisks that connect to the same target host will share the same
> set of secure communication channels.
> 
> I hope the above scheme is acceptable?
> 
> If yes, then we have a couple of options to implement this:
> 
> (1) Accept the TLS credentials per vdisk using the previously
> discussed --object tls-creds-x509 mechanism. In this case, if more
> than one vdisk have the same host info, then we will use only the
> first one's creds to set up the secure connection, and ignore the
> others. vdisks that connect to different target hosts will use their
> individual tls-creds-x509 to set up the secure channels. This is, of
> course, not relevant for qemu-img/qemu-io as they can open only one
> vdisk at a time.

It looks like option 1 here is the way to go. Just report an error if
there are multiple creds provided for the same host and they don't
match.

> 
> (2) Instead of having a per-vdisk --object tls-creds-x509, have a
> single such argument on the command line for vxhs block device code to
> consume - if that is possible! One way to achieve this could be the
> user/password authentication we discussed earlier, which we could use
> to pass the directory where cert/keys are kept.
> 
> (3) Use the instance UUID, when available, to lookup the cert files
> per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
> mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
> The cert/key files are anyway protected by file permissions in either
> case, so I guess there is no additional security provided by either
> method.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-11  3:04                                             ` ashish mittal
@ 2017-03-13  9:56                                               ` Daniel P. Berrange
  0 siblings, 0 replies; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-13  9:56 UTC (permalink / raw)
  To: ashish mittal
  Cc: Ketan Nilangekar, Jeff Cody, Stefan Hajnoczi, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Fri, Mar 10, 2017 at 07:04:38PM -0800, ashish mittal wrote:
> On Wed, Mar 8, 2017 at 10:11 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> > On Wed, Mar 08, 2017 at 09:59:32AM -0800, ashish mittal wrote:
> >> On Wed, Mar 8, 2017 at 5:04 AM, Ketan Nilangekar
> >> <Ketan.Nilangekar@veritas.com> wrote:
> >> >
> >> >
> >> >> On Mar 8, 2017, at 1:13 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> >> >>
> >> >>> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
> >> >>> Thanks! There is one more input I need some help with!
> >> >>>
> >> >>> VxHS network library opens a fixed number of connection channels to a
> >> >>> given host, and all the vdisks (that connect to the same host) share
> >> >>> these connection channels.
> >> >>>
> >> >>> Therefore, we need to open secure channels to a specific target host
> >> >>> only once for the first vdisk that connects to that host. All the
> >> >>> other vdisks that connect to the same target host will share the same
> >> >>> set of secure communication channels.
> >> >>>
> >> >>> I hope the above scheme is acceptable?
> >> >>
> >> >> I don't think I'm in favour of such an approach, as it forces a single
> >> >> QEMU process to use the same privileges for all disks it uses.
> >> >>
> >> >> Consider an example where a QEMU process has two disks, one shared
> >> >> readonly disk and one exclusive writable disk, both on the same host.
> >> >>
> >> >
> >> > This is not a use case for VxHS as a solution. We do not support sharing of vdisks across QEMU instances.
> >> >
> >> > Vxhs library was thus not designed to open different connections for individual vdisks within a QEMU instance.
> >> >
> >> > Implementing this will involve rewrite of significant parts of libvxhs client and server. Is this a new requirement for acceptance into QEMU?
> >> >
> >> >
> >> >> It is reasonable as an administrator to want to use different credentials
> >> >> for each of these. ie, they might have a set of well known credentials to
> >> >> authenticate to get access to the read-only disk, but have a different set
> >> >> of strictly limited access credentials to get access to the writable disk
> >> >>
> >> >> Trying to re-use the same connection for multiple cause prevents QEMU from
> >> >> authenticating with different credentials per disk, so I don't think that
> >> >> is a good approach - each disk should have totally independant state.
> >> >>
> >>
> >> libvxhs does not make any claim to fit all the general purpose
> >> use-cases. It was purpose-built to be the communication channel for
> >> our block device service. As such, we do not need/support all the
> >> general use-cases. For the same reason we changed the name of the
> >> library from linqnio to libvxhs (v8 changelog, #2).
> >
> > I raise these kind of points because they are relevant to apps like
> > OpenStack, against which you've proposed VHXS support. OpenStack
> > intends to allow a single volume to be shared by multiple guests,
> > so declare that out of scope you're crippling certain use cases
> > within openstack. Of course you're free to make such a decision,
> > but it makes VHXS a less compelling technology to use IMHO.
> >
> 
> Fair point! Sharing of the same disk across multiple guests would
> require significant work from our side, and we would like to evaluate
> that after OpenStack starts supporting the feature. Would adding this
> support now, be a prerequisite for merging vxhs code to qemu?

No, it isn't a requirement - just a (strong-ish) suggestion. We just need
to ensure that the CLI syntax allows us to support it in the future without
backwards incompatible changes to the CLI.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-08 18:11                                           ` Daniel P. Berrange
@ 2017-03-11  3:04                                             ` ashish mittal
  2017-03-13  9:56                                               ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-03-11  3:04 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Ketan Nilangekar, Jeff Cody, Stefan Hajnoczi, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Mar 8, 2017 at 10:11 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Wed, Mar 08, 2017 at 09:59:32AM -0800, ashish mittal wrote:
>> On Wed, Mar 8, 2017 at 5:04 AM, Ketan Nilangekar
>> <Ketan.Nilangekar@veritas.com> wrote:
>> >
>> >
>> >> On Mar 8, 2017, at 1:13 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>> >>
>> >>> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>> >>> Thanks! There is one more input I need some help with!
>> >>>
>> >>> VxHS network library opens a fixed number of connection channels to a
>> >>> given host, and all the vdisks (that connect to the same host) share
>> >>> these connection channels.
>> >>>
>> >>> Therefore, we need to open secure channels to a specific target host
>> >>> only once for the first vdisk that connects to that host. All the
>> >>> other vdisks that connect to the same target host will share the same
>> >>> set of secure communication channels.
>> >>>
>> >>> I hope the above scheme is acceptable?
>> >>
>> >> I don't think I'm in favour of such an approach, as it forces a single
>> >> QEMU process to use the same privileges for all disks it uses.
>> >>
>> >> Consider an example where a QEMU process has two disks, one shared
>> >> readonly disk and one exclusive writable disk, both on the same host.
>> >>
>> >
>> > This is not a use case for VxHS as a solution. We do not support sharing of vdisks across QEMU instances.
>> >
>> > Vxhs library was thus not designed to open different connections for individual vdisks within a QEMU instance.
>> >
>> > Implementing this will involve rewrite of significant parts of libvxhs client and server. Is this a new requirement for acceptance into QEMU?
>> >
>> >
>> >> It is reasonable as an administrator to want to use different credentials
>> >> for each of these. ie, they might have a set of well known credentials to
>> >> authenticate to get access to the read-only disk, but have a different set
>> >> of strictly limited access credentials to get access to the writable disk
>> >>
>> >> Trying to re-use the same connection for multiple cause prevents QEMU from
>> >> authenticating with different credentials per disk, so I don't think that
>> >> is a good approach - each disk should have totally independant state.
>> >>
>>
>> libvxhs does not make any claim to fit all the general purpose
>> use-cases. It was purpose-built to be the communication channel for
>> our block device service. As such, we do not need/support all the
>> general use-cases. For the same reason we changed the name of the
>> library from linqnio to libvxhs (v8 changelog, #2).
>
> I raise these kind of points because they are relevant to apps like
> OpenStack, against which you've proposed VHXS support. OpenStack
> intends to allow a single volume to be shared by multiple guests,
> so declare that out of scope you're crippling certain use cases
> within openstack. Of course you're free to make such a decision,
> but it makes VHXS a less compelling technology to use IMHO.
>

Fair point! Sharing of the same disk across multiple guests would
require significant work from our side, and we would like to evaluate
that after OpenStack starts supporting the feature. Would adding this
support now, be a prerequisite for merging vxhs code to qemu?

>> Having dedicated communication channels for each device, or sharing
>> the channels between multiple devices, should both be acceptable
>> choices. The latter, IO multiplexing, is also a widely adopted IO
>> model. It just happens to fit our use-cases better.
>>
>> Binding access control to a communication channel would prevent
>> anybody from using the latter approach. Having a separate way to allow
>> access-control would permit the use of latter also.
>
> Sharing access control across multiple disks does not fit in effectively
> with the model used by apps that manage QEMU. Libvirt, and apps above
> libvirt, like OpenStack, oVirt, and things like Kubernetes all represent
> the information required to connect to a network block device, on a
> per-disk basis - there's no sense of having some information that is
> shared across all disks associated with a VM.
>
> So from the POV of modelling this in QEMU, all information needs to be
> specified against the individual -drive / -blockdev. If you really must,
> you will just have to reject configurations which imply talking to the
> same host, with incompatible parameters. Better would be to dynamically
> determine if you can re-use connections, vs spawn new connection based
> on the config.
>

Would this be a prerequisite for merging vxhs?

> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-08 17:59                                         ` ashish mittal
@ 2017-03-08 18:11                                           ` Daniel P. Berrange
  2017-03-11  3:04                                             ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-08 18:11 UTC (permalink / raw)
  To: ashish mittal
  Cc: Ketan Nilangekar, Jeff Cody, Stefan Hajnoczi, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Mar 08, 2017 at 09:59:32AM -0800, ashish mittal wrote:
> On Wed, Mar 8, 2017 at 5:04 AM, Ketan Nilangekar
> <Ketan.Nilangekar@veritas.com> wrote:
> >
> >
> >> On Mar 8, 2017, at 1:13 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> >>
> >>> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
> >>> Thanks! There is one more input I need some help with!
> >>>
> >>> VxHS network library opens a fixed number of connection channels to a
> >>> given host, and all the vdisks (that connect to the same host) share
> >>> these connection channels.
> >>>
> >>> Therefore, we need to open secure channels to a specific target host
> >>> only once for the first vdisk that connects to that host. All the
> >>> other vdisks that connect to the same target host will share the same
> >>> set of secure communication channels.
> >>>
> >>> I hope the above scheme is acceptable?
> >>
> >> I don't think I'm in favour of such an approach, as it forces a single
> >> QEMU process to use the same privileges for all disks it uses.
> >>
> >> Consider an example where a QEMU process has two disks, one shared
> >> readonly disk and one exclusive writable disk, both on the same host.
> >>
> >
> > This is not a use case for VxHS as a solution. We do not support sharing of vdisks across QEMU instances.
> >
> > Vxhs library was thus not designed to open different connections for individual vdisks within a QEMU instance.
> >
> > Implementing this will involve rewrite of significant parts of libvxhs client and server. Is this a new requirement for acceptance into QEMU?
> >
> >
> >> It is reasonable as an administrator to want to use different credentials
> >> for each of these. ie, they might have a set of well known credentials to
> >> authenticate to get access to the read-only disk, but have a different set
> >> of strictly limited access credentials to get access to the writable disk
> >>
> >> Trying to re-use the same connection for multiple cause prevents QEMU from
> >> authenticating with different credentials per disk, so I don't think that
> >> is a good approach - each disk should have totally independant state.
> >>
> 
> libvxhs does not make any claim to fit all the general purpose
> use-cases. It was purpose-built to be the communication channel for
> our block device service. As such, we do not need/support all the
> general use-cases. For the same reason we changed the name of the
> library from linqnio to libvxhs (v8 changelog, #2).

I raise these kind of points because they are relevant to apps like
OpenStack, against which you've proposed VHXS support. OpenStack
intends to allow a single volume to be shared by multiple guests,
so declare that out of scope you're crippling certain use cases
within openstack. Of course you're free to make such a decision,
but it makes VHXS a less compelling technology to use IMHO.

> Having dedicated communication channels for each device, or sharing
> the channels between multiple devices, should both be acceptable
> choices. The latter, IO multiplexing, is also a widely adopted IO
> model. It just happens to fit our use-cases better.
> 
> Binding access control to a communication channel would prevent
> anybody from using the latter approach. Having a separate way to allow
> access-control would permit the use of latter also.

Sharing access control across multiple disks does not fit in effectively
with the model used by apps that manage QEMU. Libvirt, and apps above
libvirt, like OpenStack, oVirt, and things like Kubernetes all represent
the information required to connect to a network block device, on a
per-disk basis - there's no sense of having some information that is
shared across all disks associated with a VM.

So from the POV of modelling this in QEMU, all information needs to be
specified against the individual -drive / -blockdev. If you really must,
you will just have to reject configurations which imply talking to the
same host, with incompatible parameters. Better would be to dynamically
determine if you can re-use connections, vs spawn new connection based
on the config.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-08 13:04                                       ` Ketan Nilangekar
@ 2017-03-08 17:59                                         ` ashish mittal
  2017-03-08 18:11                                           ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-03-08 17:59 UTC (permalink / raw)
  To: Ketan Nilangekar
  Cc: Daniel P. Berrange, Jeff Cody, Stefan Hajnoczi, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Mar 8, 2017 at 5:04 AM, Ketan Nilangekar
<Ketan.Nilangekar@veritas.com> wrote:
>
>
>> On Mar 8, 2017, at 1:13 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>>
>>> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>>> Thanks! There is one more input I need some help with!
>>>
>>> VxHS network library opens a fixed number of connection channels to a
>>> given host, and all the vdisks (that connect to the same host) share
>>> these connection channels.
>>>
>>> Therefore, we need to open secure channels to a specific target host
>>> only once for the first vdisk that connects to that host. All the
>>> other vdisks that connect to the same target host will share the same
>>> set of secure communication channels.
>>>
>>> I hope the above scheme is acceptable?
>>
>> I don't think I'm in favour of such an approach, as it forces a single
>> QEMU process to use the same privileges for all disks it uses.
>>
>> Consider an example where a QEMU process has two disks, one shared
>> readonly disk and one exclusive writable disk, both on the same host.
>>
>
> This is not a use case for VxHS as a solution. We do not support sharing of vdisks across QEMU instances.
>
> Vxhs library was thus not designed to open different connections for individual vdisks within a QEMU instance.
>
> Implementing this will involve rewrite of significant parts of libvxhs client and server. Is this a new requirement for acceptance into QEMU?
>
>
>> It is reasonable as an administrator to want to use different credentials
>> for each of these. ie, they might have a set of well known credentials to
>> authenticate to get access to the read-only disk, but have a different set
>> of strictly limited access credentials to get access to the writable disk
>>
>> Trying to re-use the same connection for multiple cause prevents QEMU from
>> authenticating with different credentials per disk, so I don't think that
>> is a good approach - each disk should have totally independant state.
>>

libvxhs does not make any claim to fit all the general purpose
use-cases. It was purpose-built to be the communication channel for
our block device service. As such, we do not need/support all the
general use-cases. For the same reason we changed the name of the
library from linqnio to libvxhs (v8 changelog, #2).

Having dedicated communication channels for each device, or sharing
the channels between multiple devices, should both be acceptable
choices. The latter, IO multiplexing, is also a widely adopted IO
model. It just happens to fit our use-cases better.

Binding access control to a communication channel would prevent
anybody from using the latter approach. Having a separate way to allow
access-control would permit the use of latter also.

>>>
>>> If yes, then we have a couple of options to implement this:
>>>
>>> (1) Accept the TLS credentials per vdisk using the previously
>>> discussed --object tls-creds-x509 mechanism. In this case, if more
>>> than one vdisk have the same host info, then we will use only the
>>> first one's creds to set up the secure connection, and ignore the
>>> others. vdisks that connect to different target hosts will use their
>>> individual tls-creds-x509 to set up the secure channels. This is, of
>>> course, not relevant for qemu-img/qemu-io as they can open only one
>>> vdisk at a time.
>>>
>>> (2) Instead of having a per-vdisk --object tls-creds-x509, have a
>>> single such argument on the command line for vxhs block device code to
>>> consume - if that is possible! One way to achieve this could be the
>>> user/password authentication we discussed earlier, which we could use
>>> to pass the directory where cert/keys are kept.
>>>
>>> (3) Use the instance UUID, when available, to lookup the cert files
>>> per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
>>> mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
>>> The cert/key files are anyway protected by file permissions in either
>>> case, so I guess there is no additional security provided by either
>>> method.
>>
>> Regards,
>> Daniel
>> --
>> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
>> |: http://libvirt.org              -o-             http://virt-manager.org :|
>> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-08  9:13                                     ` Daniel P. Berrange
@ 2017-03-08 13:04                                       ` Ketan Nilangekar
  2017-03-08 17:59                                         ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Ketan Nilangekar @ 2017-03-08 13:04 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: ashish mittal, Jeff Cody, Stefan Hajnoczi, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan



> On Mar 8, 2017, at 1:13 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> 
>> On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
>> Thanks! There is one more input I need some help with!
>> 
>> VxHS network library opens a fixed number of connection channels to a
>> given host, and all the vdisks (that connect to the same host) share
>> these connection channels.
>> 
>> Therefore, we need to open secure channels to a specific target host
>> only once for the first vdisk that connects to that host. All the
>> other vdisks that connect to the same target host will share the same
>> set of secure communication channels.
>> 
>> I hope the above scheme is acceptable?
> 
> I don't think I'm in favour of such an approach, as it forces a single
> QEMU process to use the same privileges for all disks it uses.
> 
> Consider an example where a QEMU process has two disks, one shared
> readonly disk and one exclusive writable disk, both on the same host.
> 

This is not a use case for VxHS as a solution. We do not support sharing of vdisks across QEMU instances.

Vxhs library was thus not designed to open different connections for individual vdisks within a QEMU instance.

Implementing this will involve rewrite of significant parts of libvxhs client and server. Is this a new requirement for acceptance into QEMU?


> It is reasonable as an administrator to want to use different credentials
> for each of these. ie, they might have a set of well known credentials to
> authenticate to get access to the read-only disk, but have a different set
> of strictly limited access credentials to get access to the writable disk
> 
> Trying to re-use the same connection for multiple cause prevents QEMU from
> authenticating with different credentials per disk, so I don't think that
> is a good approach - each disk should have totally independant state.
> 
>> 
>> If yes, then we have a couple of options to implement this:
>> 
>> (1) Accept the TLS credentials per vdisk using the previously
>> discussed --object tls-creds-x509 mechanism. In this case, if more
>> than one vdisk have the same host info, then we will use only the
>> first one's creds to set up the secure connection, and ignore the
>> others. vdisks that connect to different target hosts will use their
>> individual tls-creds-x509 to set up the secure channels. This is, of
>> course, not relevant for qemu-img/qemu-io as they can open only one
>> vdisk at a time.
>> 
>> (2) Instead of having a per-vdisk --object tls-creds-x509, have a
>> single such argument on the command line for vxhs block device code to
>> consume - if that is possible! One way to achieve this could be the
>> user/password authentication we discussed earlier, which we could use
>> to pass the directory where cert/keys are kept.
>> 
>> (3) Use the instance UUID, when available, to lookup the cert files
>> per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
>> mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
>> The cert/key files are anyway protected by file permissions in either
>> case, so I guess there is no additional security provided by either
>> method.
> 
> Regards,
> Daniel
> -- 
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-08  1:27                                   ` ashish mittal
@ 2017-03-08  9:13                                     ` Daniel P. Berrange
  2017-03-08 13:04                                       ` Ketan Nilangekar
  2017-03-13  9:57                                     ` Daniel P. Berrange
  1 sibling, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-08  9:13 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Mar 07, 2017 at 05:27:55PM -0800, ashish mittal wrote:
> Thanks! There is one more input I need some help with!
> 
> VxHS network library opens a fixed number of connection channels to a
> given host, and all the vdisks (that connect to the same host) share
> these connection channels.
> 
> Therefore, we need to open secure channels to a specific target host
> only once for the first vdisk that connects to that host. All the
> other vdisks that connect to the same target host will share the same
> set of secure communication channels.
> 
> I hope the above scheme is acceptable?

I don't think I'm in favour of such an approach, as it forces a single
QEMU process to use the same privileges for all disks it uses.

Consider an example where a QEMU process has two disks, one shared
readonly disk and one exclusive writable disk, both on the same host.

It is reasonable as an administrator to want to use different credentials
for each of these. ie, they might have a set of well known credentials to
authenticate to get access to the read-only disk, but have a different set
of strictly limited access credentials to get access to the writable disk

Trying to re-use the same connection for multiple cause prevents QEMU from
authenticating with different credentials per disk, so I don't think that
is a good approach - each disk should have totally independant state.

 > 
> If yes, then we have a couple of options to implement this:
> 
> (1) Accept the TLS credentials per vdisk using the previously
> discussed --object tls-creds-x509 mechanism. In this case, if more
> than one vdisk have the same host info, then we will use only the
> first one's creds to set up the secure connection, and ignore the
> others. vdisks that connect to different target hosts will use their
> individual tls-creds-x509 to set up the secure channels. This is, of
> course, not relevant for qemu-img/qemu-io as they can open only one
> vdisk at a time.
> 
> (2) Instead of having a per-vdisk --object tls-creds-x509, have a
> single such argument on the command line for vxhs block device code to
> consume - if that is possible! One way to achieve this could be the
> user/password authentication we discussed earlier, which we could use
> to pass the directory where cert/keys are kept.
> 
> (3) Use the instance UUID, when available, to lookup the cert files
> per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
> mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
> The cert/key files are anyway protected by file permissions in either
> case, so I guess there is no additional security provided by either
> method.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-06  9:23                                 ` Daniel P. Berrange
@ 2017-03-08  1:27                                   ` ashish mittal
  2017-03-08  9:13                                     ` Daniel P. Berrange
  2017-03-13  9:57                                     ` Daniel P. Berrange
  0 siblings, 2 replies; 56+ messages in thread
From: ashish mittal @ 2017-03-08  1:27 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

Thanks! There is one more input I need some help with!

VxHS network library opens a fixed number of connection channels to a
given host, and all the vdisks (that connect to the same host) share
these connection channels.

Therefore, we need to open secure channels to a specific target host
only once for the first vdisk that connects to that host. All the
other vdisks that connect to the same target host will share the same
set of secure communication channels.

I hope the above scheme is acceptable?

If yes, then we have a couple of options to implement this:

(1) Accept the TLS credentials per vdisk using the previously
discussed --object tls-creds-x509 mechanism. In this case, if more
than one vdisk have the same host info, then we will use only the
first one's creds to set up the secure connection, and ignore the
others. vdisks that connect to different target hosts will use their
individual tls-creds-x509 to set up the secure channels. This is, of
course, not relevant for qemu-img/qemu-io as they can open only one
vdisk at a time.

(2) Instead of having a per-vdisk --object tls-creds-x509, have a
single such argument on the command line for vxhs block device code to
consume - if that is possible! One way to achieve this could be the
user/password authentication we discussed earlier, which we could use
to pass the directory where cert/keys are kept.

(3) Use the instance UUID, when available, to lookup the cert files
per instance (i.e. for qemu-kvm), and use the --object tls-creds-x509
mechanism, when instance UUID is NULL (i.e. qemu-io, qemu-img etc).
The cert/key files are anyway protected by file permissions in either
case, so I guess there is no additional security provided by either
method.

Regards,
Ashish

On Mon, Mar 6, 2017 at 1:23 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Sun, Mar 05, 2017 at 04:26:05PM -0800, ashish mittal wrote:
>> On Wed, Mar 1, 2017 at 1:18 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>> >
>> > Yes, that's how other parts of QEMU deal with SSL
>> >
>> > NB, QEMU needs to pass 3 paths to libqnoio - the client cert, the
>> > client key, and the certificate authority certlist
>> >
>>
>> I see that the QEMU TLS code internally does expect to find cacert,
>> and errors out if this is missing. I did have to create one and place
>> it in the dir path where we are keeping the client key,cert files. The
>> code diff below requires all the three files.
>
> Yes, the client cert/key have to be paired with the correct CA cert. We cannot
> assume that the default CA cert bundle contains the right CA, for use with the
> cert/key. The default CA bundle contains all the public commercial CAs, and in
> general a QEMU deployment will never use any of those - the site will use a
> private internal only CA. While you could add the private CA to the global CA
> bundle, that is not desirable from a security POV, as it opens the deployment
> to risk from a rogue CA.
>
>> > The include/crypto/tlscredsx509.h file has constants defined for the
>> > standard filenames - eg you would concatenate the directory with
>> > the constants QCRYPTO_TLS_CREDS_X509_CLIENT_KEY.
>> >
>> > This gives the filenames you can then pass to libqnio
>> >
>>
>> I am using function qcrypto_tls_creds_get_path() to achieve the same.
>> Hope this is OK.
>
> Yep, that's fine.
>
>> Example CLI accepting the new TLS credentials:
>>
>> [amittal2@camshaft qemu] 2017-03-05 15:54:55$ ./qemu-io --trace
>> enable=vxhs* --object
>> tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client -c 'read
>> 66000 128k' 'json:{"server.host": "127.0.0.1", "server.port": "9999",
>> "vdisk-id": "/test.raw", "driver": "vxhs", "tls-creds":"tls0"}'
>> 15116@1488758101.084355:vxhs_open_vdiskid Opening vdisk-id /test.raw
>> 15116@1488758101.084396:vxhs_get_creds cacert
>> /etc/pki/qemu/vxhs/ca-cert.pem, client_key
>> /etc/pki/qemu/vxhs/client-key.pem, client_cert
>> /etc/pki/qemu/vxhs/client-cert.pem   <===== !!!! NOTE !!!!
>> 15116@1488758101.084402:vxhs_open_hostinfo Adding host 127.0.0.1:9999
>> to BDRVVXHSState
>> 15116@1488758101.092060:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
>> returned size 1048576
>> read 131072/131072 bytes at offset 66000
>> 128 KiB, 1 ops; 0.0006 sec (188.537 MiB/sec and 1508.2956 ops/sec)
>> 15116@1488758101.094643:vxhs_close Closing vdisk /test.raw
>> [amittal2@camshaft qemu] 2017-03-05 15:55:01$
>
> That looks ok.
>
>> @@ -315,33 +374,39 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>>      if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
>>          error_setg(&local_err, "server.host cannot be more than %d characters",
>>                     MAXHOSTNAMELEN);
>> -        qdict_del(backing_options, str);
>>          ret = -EINVAL;
>>          goto out;
>>      }
>>
>> -    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
>> +    /* check if we got tls-creds via the --object argument */
>> +    s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
>> +    if (s->tlscredsid) {
>> +        vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
>> +                           &client_cert, &local_err);
>> +        if (local_err != NULL) {
>> +            ret = -EINVAL;
>> +            goto out;
>> +        }
>> +        trace_vxhs_get_creds(cacert, client_key, client_cert);
>> +    }
>>
>> +    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
>>      s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
>>                                                            VXHS_OPT_PORT),
>>                                                            NULL, 0);
>>
>>      trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
>> -                         s->vdisk_hostinfo.port);
>> -
>> -    /* free the 'server.' entries allocated by previous call to
>> -     * qdict_extract_subqdict()
>> -     */
>> -    qdict_del(backing_options, str);
>> +                             s->vdisk_hostinfo.port);
>>
>>      of_vsa_addr = g_strdup_printf("of://%s:%d",
>> -                                s->vdisk_hostinfo.host,
>> -                                s->vdisk_hostinfo.port);
>> +                                  s->vdisk_hostinfo.host,
>> +                                  s->vdisk_hostinfo.port);
>>
>>      /*
>>       * Open qnio channel to storage agent if not opened before.
>>       */
>> -    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0);
>> +    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
>> +                           client_key, client_cert);
>
> You need to pass  ca_cert into this method too.
>
>
> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-06  0:26                               ` ashish mittal
@ 2017-03-06  9:23                                 ` Daniel P. Berrange
  2017-03-08  1:27                                   ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-06  9:23 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Sun, Mar 05, 2017 at 04:26:05PM -0800, ashish mittal wrote:
> On Wed, Mar 1, 2017 at 1:18 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> >
> > Yes, that's how other parts of QEMU deal with SSL
> >
> > NB, QEMU needs to pass 3 paths to libqnoio - the client cert, the
> > client key, and the certificate authority certlist
> >
> 
> I see that the QEMU TLS code internally does expect to find cacert,
> and errors out if this is missing. I did have to create one and place
> it in the dir path where we are keeping the client key,cert files. The
> code diff below requires all the three files.

Yes, the client cert/key have to be paired with the correct CA cert. We cannot
assume that the default CA cert bundle contains the right CA, for use with the
cert/key. The default CA bundle contains all the public commercial CAs, and in
general a QEMU deployment will never use any of those - the site will use a
private internal only CA. While you could add the private CA to the global CA
bundle, that is not desirable from a security POV, as it opens the deployment
to risk from a rogue CA.

> > The include/crypto/tlscredsx509.h file has constants defined for the
> > standard filenames - eg you would concatenate the directory with
> > the constants QCRYPTO_TLS_CREDS_X509_CLIENT_KEY.
> >
> > This gives the filenames you can then pass to libqnio
> >
> 
> I am using function qcrypto_tls_creds_get_path() to achieve the same.
> Hope this is OK.

Yep, that's fine.

> Example CLI accepting the new TLS credentials:
> 
> [amittal2@camshaft qemu] 2017-03-05 15:54:55$ ./qemu-io --trace
> enable=vxhs* --object
> tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client -c 'read
> 66000 128k' 'json:{"server.host": "127.0.0.1", "server.port": "9999",
> "vdisk-id": "/test.raw", "driver": "vxhs", "tls-creds":"tls0"}'
> 15116@1488758101.084355:vxhs_open_vdiskid Opening vdisk-id /test.raw
> 15116@1488758101.084396:vxhs_get_creds cacert
> /etc/pki/qemu/vxhs/ca-cert.pem, client_key
> /etc/pki/qemu/vxhs/client-key.pem, client_cert
> /etc/pki/qemu/vxhs/client-cert.pem   <===== !!!! NOTE !!!!
> 15116@1488758101.084402:vxhs_open_hostinfo Adding host 127.0.0.1:9999
> to BDRVVXHSState
> 15116@1488758101.092060:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
> returned size 1048576
> read 131072/131072 bytes at offset 66000
> 128 KiB, 1 ops; 0.0006 sec (188.537 MiB/sec and 1508.2956 ops/sec)
> 15116@1488758101.094643:vxhs_close Closing vdisk /test.raw
> [amittal2@camshaft qemu] 2017-03-05 15:55:01$

That looks ok.

> @@ -315,33 +374,39 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>      if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
>          error_setg(&local_err, "server.host cannot be more than %d characters",
>                     MAXHOSTNAMELEN);
> -        qdict_del(backing_options, str);
>          ret = -EINVAL;
>          goto out;
>      }
> 
> -    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
> +    /* check if we got tls-creds via the --object argument */
> +    s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
> +    if (s->tlscredsid) {
> +        vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
> +                           &client_cert, &local_err);
> +        if (local_err != NULL) {
> +            ret = -EINVAL;
> +            goto out;
> +        }
> +        trace_vxhs_get_creds(cacert, client_key, client_cert);
> +    }
> 
> +    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
>      s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
>                                                            VXHS_OPT_PORT),
>                                                            NULL, 0);
> 
>      trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
> -                         s->vdisk_hostinfo.port);
> -
> -    /* free the 'server.' entries allocated by previous call to
> -     * qdict_extract_subqdict()
> -     */
> -    qdict_del(backing_options, str);
> +                             s->vdisk_hostinfo.port);
> 
>      of_vsa_addr = g_strdup_printf("of://%s:%d",
> -                                s->vdisk_hostinfo.host,
> -                                s->vdisk_hostinfo.port);
> +                                  s->vdisk_hostinfo.host,
> +                                  s->vdisk_hostinfo.port);
> 
>      /*
>       * Open qnio channel to storage agent if not opened before.
>       */
> -    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0);
> +    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
> +                           client_key, client_cert);

You need to pass  ca_cert into this method too.


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-03-01  9:18                             ` Daniel P. Berrange
@ 2017-03-06  0:26                               ` ashish mittal
  2017-03-06  9:23                                 ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-03-06  0:26 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Mar 1, 2017 at 1:18 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Tue, Feb 28, 2017 at 02:51:39PM -0800, ashish mittal wrote:
>> On Mon, Feb 27, 2017 at 1:22 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
>
>> >> +        ret = -EINVAL;
>> >> +        goto out;
>> >> +    }
>> >> +
>> >> +    secretid = qemu_opt_get(opts, VXHS_OPT_SECRETID);
>> >> +    if (!secretid) {
>> >> +        error_setg(&local_err, "please specify the ID of the secret to be "
>> >> +                   "used for authenticating to target");
>> >> +        qdict_del(backing_options, str);
>> >> +        ret = -EINVAL;
>> >> +        goto out;
>> >> +    }
>> >> +
>> >> +    /* check if we got password via the --object argument */
>> >> +    password = qcrypto_secret_lookup_as_utf8(secretid, &local_err);
>> >> +    if (local_err != NULL) {
>> >> +        trace_vxhs_get_creds(user, secretid, password);
>> >> +        qdict_del(backing_options, str);
>> >> +        ret = -EINVAL;
>> >> +        goto out;
>> >> +    }
>> >> +    trace_vxhs_get_creds(user, secretid, password);
>> >> +
>> >>      s->vdisk_hostinfo.host = g_strdup(server_host_opt);
>> >>
>> >>      s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
>>
>> The next thing we need consensus on, is to decide exactly what
>> additional information to pass.
>>
>> (1) Current security implementation in VxHS uses the SSL key and
>> certificate files. Do you think we can achieve all the intended
>> security goals if we pass these two files paths (and names?) from the
>> command line?
>
> Yes, that's how other parts of QEMU deal with SSL
>
> NB, QEMU needs to pass 3 paths to libqnoio - the client cert, the
> client key, and the certificate authority certlist
>

I see that the QEMU TLS code internally does expect to find cacert,
and errors out if this is missing. I did have to create one and place
it in the dir path where we are keeping the client key,cert files. The
code diff below requires all the three files.

Here are the files I had to create -
$ ll /etc/pki/qemu/vxhs
total 12
-r--r--r--. 1 root root 2094 Mar  4 18:02 ca-cert.pem
-r--r--r--. 1 root root 1899 Mar  4 18:00 client-cert.pem
-r--r--r--. 1 root root 1679 Mar  4 17:59 client-key.pem

>> (2) If we are OK to continue with the present security scheme (using
>> key and cert), then the only additional change needed might be to
>> accept these files on the command line.
>
> Yep, I think that's the minimum required change to make this mergable.
>
>> (3) If we decide to rely on file permissions and SELinux policy to
>> protect these key/cert files, then we don't need to pass the file
>> names as a secret, instead, passing them as regular qemu_opt_get()
>> options might be enough.
>
> That's correct - you can assume file permissions protect the cert
> files. I would expect the syntax to work as follows
>
>   $QEMU  -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client \
>          -drive  driver=vxhs,...other..opts...,tls-creds=tls0
>
> When you see the 'tls-creds' flag, you can lookup the corresponding
> QCryptoTLSCredsX509 object and extract the 'dir' property from it.
>

The code diff below works as above. Please verify.

> The include/crypto/tlscredsx509.h file has constants defined for the
> standard filenames - eg you would concatenate the directory with
> the constants QCRYPTO_TLS_CREDS_X509_CLIENT_KEY.
>
> This gives the filenames you can then pass to libqnio
>

I am using function qcrypto_tls_creds_get_path() to achieve the same.
Hope this is OK.

> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|


Example CLI accepting the new TLS credentials:

[amittal2@camshaft qemu] 2017-03-05 15:54:55$ ./qemu-io --trace
enable=vxhs* --object
tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client -c 'read
66000 128k' 'json:{"server.host": "127.0.0.1", "server.port": "9999",
"vdisk-id": "/test.raw", "driver": "vxhs", "tls-creds":"tls0"}'
15116@1488758101.084355:vxhs_open_vdiskid Opening vdisk-id /test.raw
15116@1488758101.084396:vxhs_get_creds cacert
/etc/pki/qemu/vxhs/ca-cert.pem, client_key
/etc/pki/qemu/vxhs/client-key.pem, client_cert
/etc/pki/qemu/vxhs/client-cert.pem   <===== !!!! NOTE !!!!
15116@1488758101.084402:vxhs_open_hostinfo Adding host 127.0.0.1:9999
to BDRVVXHSState
15116@1488758101.092060:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
returned size 1048576
read 131072/131072 bytes at offset 66000
128 KiB, 1 ops; 0.0006 sec (188.537 MiB/sec and 1508.2956 ops/sec)
15116@1488758101.094643:vxhs_close Closing vdisk /test.raw
[amittal2@camshaft qemu] 2017-03-05 15:55:01$

NB - I am passing client-key and client-cert to iio_open() here.
libqnio changes to work with these new args via iio_open() will
follow.

diff --git a/block/trace-events b/block/trace-events
index f193079..7758ec3 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -126,3 +126,4 @@ vxhs_open_hostinfo(char *of_vsa_addr, int port)
"Adding host %s:%d to BDRVVXHSSt
 vxhs_open_iio_open(const char *host) "Failed to connect to storage
agent on host %s"
 vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d"
 vxhs_close(char *vdisk_guid) "Closing vdisk %s"
+vxhs_get_creds(const char *cacert, const char *client_key, const char
*client_cert) "cacert %s, client_key %s, client_cert %s"
diff --git a/block/vxhs.c b/block/vxhs.c
index 4f0633e..3e429e2 100644
--- a/block/vxhs.c
+++ b/block/vxhs.c
@@ -17,6 +17,9 @@
 #include "qemu/uri.h"
 #include "qapi/error.h"
 #include "qemu/uuid.h"
+#include "crypto/secret.h"
+#include "crypto/tlscredsx509.h"
+#include "crypto/tlscredspriv.h"

 #define VXHS_OPT_FILENAME           "filename"
 #define VXHS_OPT_VDISK_ID           "vdisk-id"
@@ -55,6 +58,7 @@ typedef struct VXHSvDiskHostsInfo {
 typedef struct BDRVVXHSState {
     VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
     char *vdisk_guid;
+    char *tlscredsid; /* tlscredsid */
 } BDRVVXHSState;

 static void vxhs_complete_aio_bh(void *opaque)
@@ -136,6 +140,11 @@ static QemuOptsList runtime_opts = {
             .type = QEMU_OPT_STRING,
             .help = "UUID of the VxHS vdisk",
         },
+        {
+            .name = "tls-creds",
+            .type = QEMU_OPT_STRING,
+            .help = "ID of the TLS/SSL credentials to use",
+        },
         { /* end of list */ }
     },
 };
@@ -244,6 +253,55 @@ static void vxhs_unref(void)
     }
 }

+static void vxhs_get_tls_creds(const char *id, char **cacert,
+                               char **key, char **cert, Error **errp)
+{
+    Object *obj;
+    QCryptoTLSCreds *creds = NULL;
+    QCryptoTLSCredsX509 *creds_x509 = NULL;
+
+    obj = object_resolve_path_component(
+        object_get_objects_root(), id);
+
+    if (!obj) {
+        error_setg(errp, "No TLS credentials with id '%s'",
+                   id);
+        return;
+    }
+
+    creds_x509 = (QCryptoTLSCredsX509 *)
+        object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS_X509);
+
+    if (!creds_x509) {
+        error_setg(errp, "Object with id '%s' is not TLS credentials",
+                   id);
+        return;
+    }
+
+    creds = &creds_x509->parent_obj;
+
+    if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
+        error_setg(errp,
+                   "Expecting TLS credentials with a client endpoint");
+        return;
+    }
+
+    /*
+     * Get the cacert, client_cert and client_key file names.
+     */
+    if (qcrypto_tls_creds_get_path(creds, QCRYPTO_TLS_CREDS_X509_CA_CERT,
+                                   true, cacert, errp) < 0 ||
+        qcrypto_tls_creds_get_path(&creds_x509->parent_obj,
+                                   QCRYPTO_TLS_CREDS_X509_CLIENT_CERT,
+                                   false, cert, errp) < 0 ||
+        qcrypto_tls_creds_get_path(&creds_x509->parent_obj,
+                                   QCRYPTO_TLS_CREDS_X509_CLIENT_KEY,
+                                   false, key, errp) < 0) {
+        error_setg(errp,
+                   "Error retrieving information from  TLS object");
+    }
+}
+
 static int vxhs_open(BlockDriverState *bs, QDict *options,
                      int bdrv_flags, Error **errp)
 {
@@ -257,6 +315,9 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     const char *server_host_opt;
     char *str = NULL;
     int ret = 0;
+    char *cacert = NULL;
+    char *client_key = NULL;
+    char *client_cert = NULL;

     ret = vxhs_init_and_ref();
     if (ret < 0) {
@@ -297,8 +358,7 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     qdict_extract_subqdict(options, &backing_options, str);

     qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
-    if (local_err) {
-        qdict_del(backing_options, str);
+    if (local_err != NULL) {
         ret = -EINVAL;
         goto out;
     }
@@ -307,7 +367,6 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     if (!server_host_opt) {
         error_setg(&local_err, QERR_MISSING_PARAMETER,
                    VXHS_OPT_SERVER"."VXHS_OPT_HOST);
-        qdict_del(backing_options, str);
         ret = -EINVAL;
         goto out;
     }
@@ -315,33 +374,39 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
         error_setg(&local_err, "server.host cannot be more than %d characters",
                    MAXHOSTNAMELEN);
-        qdict_del(backing_options, str);
         ret = -EINVAL;
         goto out;
     }

-    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
+    /* check if we got tls-creds via the --object argument */
+    s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
+    if (s->tlscredsid) {
+        vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
+                           &client_cert, &local_err);
+        if (local_err != NULL) {
+            ret = -EINVAL;
+            goto out;
+        }
+        trace_vxhs_get_creds(cacert, client_key, client_cert);
+    }

+    s->vdisk_hostinfo.host = g_strdup(server_host_opt);
     s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
                                                           VXHS_OPT_PORT),
                                                           NULL, 0);

     trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
-                         s->vdisk_hostinfo.port);
-
-    /* free the 'server.' entries allocated by previous call to
-     * qdict_extract_subqdict()
-     */
-    qdict_del(backing_options, str);
+                             s->vdisk_hostinfo.port);

     of_vsa_addr = g_strdup_printf("of://%s:%d",
-                                s->vdisk_hostinfo.host,
-                                s->vdisk_hostinfo.port);
+                                  s->vdisk_hostinfo.host,
+                                  s->vdisk_hostinfo.port);

     /*
      * Open qnio channel to storage agent if not opened before.
      */
-    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0);
+    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
+                           client_key, client_cert);
    <===== !!!! NOTE !!!!
     if (dev_handlep == NULL) {
         trace_vxhs_open_iio_open(of_vsa_addr);
         ret = -ENODEV;
@@ -355,12 +420,16 @@ out:
     QDECREF(backing_options);
     qemu_opts_del(tcp_opts);
     qemu_opts_del(opts);
+    g_free(cacert);
+    g_free(client_key);
+    g_free(client_cert);

     if (ret < 0) {
         vxhs_unref();
         error_propagate(errp, local_err);
         g_free(s->vdisk_hostinfo.host);
         g_free(s->vdisk_guid);
+        g_free(s->tlscredsid);
         s->vdisk_guid = NULL;
         errno = -ret;
     }
@@ -466,9 +535,11 @@ static void vxhs_close(BlockDriverState *bs)
     vxhs_unref();

     /*
-     * Free the dynamically allocated host string
+     * Free the dynamically allocated host string etc
      */
     g_free(s->vdisk_hostinfo.host);
+    g_free(s->tlscredsid);
+    s->tlscredsid = NULL;


Regards,
Ashish

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-28 22:51                           ` ashish mittal
@ 2017-03-01  9:18                             ` Daniel P. Berrange
  2017-03-06  0:26                               ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-03-01  9:18 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 28, 2017 at 02:51:39PM -0800, ashish mittal wrote:
> On Mon, Feb 27, 2017 at 1:22 AM, Daniel P. Berrange <berrange@redhat.com> wrote:

> >> +        ret = -EINVAL;
> >> +        goto out;
> >> +    }
> >> +
> >> +    secretid = qemu_opt_get(opts, VXHS_OPT_SECRETID);
> >> +    if (!secretid) {
> >> +        error_setg(&local_err, "please specify the ID of the secret to be "
> >> +                   "used for authenticating to target");
> >> +        qdict_del(backing_options, str);
> >> +        ret = -EINVAL;
> >> +        goto out;
> >> +    }
> >> +
> >> +    /* check if we got password via the --object argument */
> >> +    password = qcrypto_secret_lookup_as_utf8(secretid, &local_err);
> >> +    if (local_err != NULL) {
> >> +        trace_vxhs_get_creds(user, secretid, password);
> >> +        qdict_del(backing_options, str);
> >> +        ret = -EINVAL;
> >> +        goto out;
> >> +    }
> >> +    trace_vxhs_get_creds(user, secretid, password);
> >> +
> >>      s->vdisk_hostinfo.host = g_strdup(server_host_opt);
> >>
> >>      s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
> 
> The next thing we need consensus on, is to decide exactly what
> additional information to pass.
> 
> (1) Current security implementation in VxHS uses the SSL key and
> certificate files. Do you think we can achieve all the intended
> security goals if we pass these two files paths (and names?) from the
> command line?

Yes, that's how other parts of QEMU deal with SSL

NB, QEMU needs to pass 3 paths to libqnoio - the client cert, the
client key, and the certificate authority certlist 

> (2) If we are OK to continue with the present security scheme (using
> key and cert), then the only additional change needed might be to
> accept these files on the command line.

Yep, I think that's the minimum required change to make this mergable.

> (3) If we decide to rely on file permissions and SELinux policy to
> protect these key/cert files, then we don't need to pass the file
> names as a secret, instead, passing them as regular qemu_opt_get()
> options might be enough.

That's correct - you can assume file permissions protect the cert
files. I would expect the syntax to work as follows

  $QEMU  -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client \
         -drive  driver=vxhs,...other..opts...,tls-creds=tls0

When you see the 'tls-creds' flag, you can lookup the corresponding
QCryptoTLSCredsX509 object and extract the 'dir' property from it.

The include/crypto/tlscredsx509.h file has constants defined for the
standard filenames - eg you would concatenate the directory with
the constants QCRYPTO_TLS_CREDS_X509_CLIENT_KEY.

This gives the filenames you can then pass to libqnio

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-27  9:22                         ` Daniel P. Berrange
@ 2017-02-28 22:51                           ` ashish mittal
  2017-03-01  9:18                             ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-28 22:51 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Mon, Feb 27, 2017 at 1:22 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Fri, Feb 24, 2017 at 03:30:21PM -0800, ashish mittal wrote:
>> Thanks!
>>
>> I hope the following is in line with what you suggested -
>
> Yes, that looks suitable for password auth
>
Thanks!

>>
>> We will error out in case either of username, secret-id, or password
>> are missing.
>>
>> Good case, passing password via a file -
>> $ ./qemu-io --trace enable=vxhs* --object
>> secret,id=xvxhspasswd,file=/tmp/some/file/path  -c 'read 66000 128k'
>> 'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
>> "/test.raw", "driver": "vxhs", "user": "ashish",  "password-secret":
>> "xvxhspasswd"}'
>> 1132@1487977829.151064:vxhs_open_vdiskid Opening vdisk-id /test.raw
>>
>> 1132@1487977829.151141:vxhs_get_creds User ashish, SecretID
>> xvxhspasswd, Password Str0ngP@ssw0rd   <=== ****  NOTE WILL NOT PRINT
>> PASSWORD IN FINAL CODE ****
>>
>> 1132@1487977829.151168:vxhs_open_hostinfo Adding host 127.0.0.1:9999
>> to BDRVVXHSState
>> 1132@1487977829.173062:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
>> returned size 196616
>> read 131072/131072 bytes at offset 66000
>> 128 KiB, 1 ops; 0.0012 sec (99.049 MiB/sec and 792.3930 ops/sec)
>> 1132@1487977829.175141:vxhs_close Closing vdisk /test.raw
>>
>>
>> Bad case, missing user -
>> $ ./qemu-io --trace enable=vxhs* --object
>> secret,id=xvxhspasswd,data=/tmp/some/file/path  -c 'read 66000 128k'
>> 'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
>> "/test.raw", "driver": "vxhs"}'
>> 1310@1487978547.771234:vxhs_open_vdiskid Opening vdisk-id /test.raw
>> can't open device json:{"server.host": "127.0.0.1", "server.port":
>> "9999", "vdisk-id": "/test.raw", "driver": "vxhs"}: please specify the
>> user for authenticating to target
>>
>> diff --git a/block/vxhs.c b/block/vxhs.c
>> index 4f0633e..9b60ddf 100644
>> --- a/block/vxhs.c
>> +++ b/block/vxhs.c
>> @@ -17,12 +17,16 @@
>>  #include "qemu/uri.h"
>>  #include "qapi/error.h"
>>  #include "qemu/uuid.h"
>> +#include "crypto/secret.h"
>>
>>  #define VXHS_OPT_FILENAME           "filename"
>>  #define VXHS_OPT_VDISK_ID           "vdisk-id"
>>  #define VXHS_OPT_SERVER             "server"
>>  #define VXHS_OPT_HOST               "host"
>>  #define VXHS_OPT_PORT               "port"
>> +#define VXHS_OPT_USER               "user"
>> +#define VXHS_OPT_PASSWORD           "password"
>> +#define VXHS_OPT_SECRETID           "password-secret"
>>  #define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
>>
>>  QemuUUID qemu_uuid __attribute__ ((weak));
>> @@ -136,6 +140,22 @@ static QemuOptsList runtime_opts = {
>>              .type = QEMU_OPT_STRING,
>>              .help = "UUID of the VxHS vdisk",
>>          },
>> +        {
>> +            .name = VXHS_OPT_USER,
>> +            .type = QEMU_OPT_STRING,
>> +            .help = "username for authentication to target",
>> +        },
>> +        {
>> +            .name = VXHS_OPT_PASSWORD,
>> +            .type = QEMU_OPT_STRING,
>> +            .help = "password for authentication to target",
>> +        },
>> +        {
>> +            .name = VXHS_OPT_SECRETID,
>> +            .type = QEMU_OPT_STRING,
>> +            .help = "ID of the secret providing password for"
>> +                    "authentication to target",
>> +        },
>>          { /* end of list */ }
>>      },
>>  };
>> @@ -257,6 +277,9 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>>      const char *server_host_opt;
>>      char *str = NULL;
>>      int ret = 0;
>> +    const char *user = NULL;
>> +    const char *secretid = NULL;
>> +    const char *password = NULL;
>>
>>      ret = vxhs_init_and_ref();
>>      if (ret < 0) {
>> @@ -320,6 +343,35 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>>          goto out;
>>      }
>>
>> +    /* check if we got username and secretid via the options */
>> +    user = qemu_opt_get(opts, VXHS_OPT_USER);
>> +    if (!user) {
>> +        error_setg(&local_err, "please specify the user for authenticating to "
>> +                   "target");
>> +        qdict_del(backing_options, str);
>
> Not sure why you're deleting this ? Likewise the 2 cases below too
>

Picked it up from qemu_gluster_parse_json(). I will get rid of them in
the final version.

>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    secretid = qemu_opt_get(opts, VXHS_OPT_SECRETID);
>> +    if (!secretid) {
>> +        error_setg(&local_err, "please specify the ID of the secret to be "
>> +                   "used for authenticating to target");
>> +        qdict_del(backing_options, str);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    /* check if we got password via the --object argument */
>> +    password = qcrypto_secret_lookup_as_utf8(secretid, &local_err);
>> +    if (local_err != NULL) {
>> +        trace_vxhs_get_creds(user, secretid, password);
>> +        qdict_del(backing_options, str);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +    trace_vxhs_get_creds(user, secretid, password);
>> +
>>      s->vdisk_hostinfo.host = g_strdup(server_host_opt);
>>
>>      s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
>
> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

The next thing we need consensus on, is to decide exactly what
additional information to pass.

(1) Current security implementation in VxHS uses the SSL key and
certificate files. Do you think we can achieve all the intended
security goals if we pass these two files paths (and names?) from the
command line?

(2) If we are OK to continue with the present security scheme (using
key and cert), then the only additional change needed might be to
accept these files on the command line.

(3) If we decide to rely on file permissions and SELinux policy to
protect these key/cert files, then we don't need to pass the file
names as a secret, instead, passing them as regular qemu_opt_get()
options might be enough.

Let us know what you think about the above?

Thanks,
Ashish

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-24 23:30                       ` ashish mittal
@ 2017-02-27  9:22                         ` Daniel P. Berrange
  2017-02-28 22:51                           ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-27  9:22 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Fri, Feb 24, 2017 at 03:30:21PM -0800, ashish mittal wrote:
> Thanks!
> 
> I hope the following is in line with what you suggested -

Yes, that looks suitable for password auth

> 
> We will error out in case either of username, secret-id, or password
> are missing.
> 
> Good case, passing password via a file -
> $ ./qemu-io --trace enable=vxhs* --object
> secret,id=xvxhspasswd,file=/tmp/some/file/path  -c 'read 66000 128k'
> 'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
> "/test.raw", "driver": "vxhs", "user": "ashish",  "password-secret":
> "xvxhspasswd"}'
> 1132@1487977829.151064:vxhs_open_vdiskid Opening vdisk-id /test.raw
> 
> 1132@1487977829.151141:vxhs_get_creds User ashish, SecretID
> xvxhspasswd, Password Str0ngP@ssw0rd   <=== ****  NOTE WILL NOT PRINT
> PASSWORD IN FINAL CODE ****
> 
> 1132@1487977829.151168:vxhs_open_hostinfo Adding host 127.0.0.1:9999
> to BDRVVXHSState
> 1132@1487977829.173062:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
> returned size 196616
> read 131072/131072 bytes at offset 66000
> 128 KiB, 1 ops; 0.0012 sec (99.049 MiB/sec and 792.3930 ops/sec)
> 1132@1487977829.175141:vxhs_close Closing vdisk /test.raw
> 
> 
> Bad case, missing user -
> $ ./qemu-io --trace enable=vxhs* --object
> secret,id=xvxhspasswd,data=/tmp/some/file/path  -c 'read 66000 128k'
> 'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
> "/test.raw", "driver": "vxhs"}'
> 1310@1487978547.771234:vxhs_open_vdiskid Opening vdisk-id /test.raw
> can't open device json:{"server.host": "127.0.0.1", "server.port":
> "9999", "vdisk-id": "/test.raw", "driver": "vxhs"}: please specify the
> user for authenticating to target
> 
> diff --git a/block/vxhs.c b/block/vxhs.c
> index 4f0633e..9b60ddf 100644
> --- a/block/vxhs.c
> +++ b/block/vxhs.c
> @@ -17,12 +17,16 @@
>  #include "qemu/uri.h"
>  #include "qapi/error.h"
>  #include "qemu/uuid.h"
> +#include "crypto/secret.h"
> 
>  #define VXHS_OPT_FILENAME           "filename"
>  #define VXHS_OPT_VDISK_ID           "vdisk-id"
>  #define VXHS_OPT_SERVER             "server"
>  #define VXHS_OPT_HOST               "host"
>  #define VXHS_OPT_PORT               "port"
> +#define VXHS_OPT_USER               "user"
> +#define VXHS_OPT_PASSWORD           "password"
> +#define VXHS_OPT_SECRETID           "password-secret"
>  #define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"
> 
>  QemuUUID qemu_uuid __attribute__ ((weak));
> @@ -136,6 +140,22 @@ static QemuOptsList runtime_opts = {
>              .type = QEMU_OPT_STRING,
>              .help = "UUID of the VxHS vdisk",
>          },
> +        {
> +            .name = VXHS_OPT_USER,
> +            .type = QEMU_OPT_STRING,
> +            .help = "username for authentication to target",
> +        },
> +        {
> +            .name = VXHS_OPT_PASSWORD,
> +            .type = QEMU_OPT_STRING,
> +            .help = "password for authentication to target",
> +        },
> +        {
> +            .name = VXHS_OPT_SECRETID,
> +            .type = QEMU_OPT_STRING,
> +            .help = "ID of the secret providing password for"
> +                    "authentication to target",
> +        },
>          { /* end of list */ }
>      },
>  };
> @@ -257,6 +277,9 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>      const char *server_host_opt;
>      char *str = NULL;
>      int ret = 0;
> +    const char *user = NULL;
> +    const char *secretid = NULL;
> +    const char *password = NULL;
> 
>      ret = vxhs_init_and_ref();
>      if (ret < 0) {
> @@ -320,6 +343,35 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>          goto out;
>      }
> 
> +    /* check if we got username and secretid via the options */
> +    user = qemu_opt_get(opts, VXHS_OPT_USER);
> +    if (!user) {
> +        error_setg(&local_err, "please specify the user for authenticating to "
> +                   "target");
> +        qdict_del(backing_options, str);

Not sure why you're deleting this ? Likewise the 2 cases below too

> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    secretid = qemu_opt_get(opts, VXHS_OPT_SECRETID);
> +    if (!secretid) {
> +        error_setg(&local_err, "please specify the ID of the secret to be "
> +                   "used for authenticating to target");
> +        qdict_del(backing_options, str);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    /* check if we got password via the --object argument */
> +    password = qcrypto_secret_lookup_as_utf8(secretid, &local_err);
> +    if (local_err != NULL) {
> +        trace_vxhs_get_creds(user, secretid, password);
> +        qdict_del(backing_options, str);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +    trace_vxhs_get_creds(user, secretid, password);
> +
>      s->vdisk_hostinfo.host = g_strdup(server_host_opt);
> 
>      s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-24  9:19                     ` Daniel P. Berrange
@ 2017-02-24 23:30                       ` ashish mittal
  2017-02-27  9:22                         ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-24 23:30 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

Thanks!

I hope the following is in line with what you suggested -

We will error out in case either of username, secret-id, or password
are missing.

Good case, passing password via a file -
$ ./qemu-io --trace enable=vxhs* --object
secret,id=xvxhspasswd,file=/tmp/some/file/path  -c 'read 66000 128k'
'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
"/test.raw", "driver": "vxhs", "user": "ashish",  "password-secret":
"xvxhspasswd"}'
1132@1487977829.151064:vxhs_open_vdiskid Opening vdisk-id /test.raw

1132@1487977829.151141:vxhs_get_creds User ashish, SecretID
xvxhspasswd, Password Str0ngP@ssw0rd   <=== ****  NOTE WILL NOT PRINT
PASSWORD IN FINAL CODE ****

1132@1487977829.151168:vxhs_open_hostinfo Adding host 127.0.0.1:9999
to BDRVVXHSState
1132@1487977829.173062:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
returned size 196616
read 131072/131072 bytes at offset 66000
128 KiB, 1 ops; 0.0012 sec (99.049 MiB/sec and 792.3930 ops/sec)
1132@1487977829.175141:vxhs_close Closing vdisk /test.raw


Bad case, missing user -
$ ./qemu-io --trace enable=vxhs* --object
secret,id=xvxhspasswd,data=/tmp/some/file/path  -c 'read 66000 128k'
'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
"/test.raw", "driver": "vxhs"}'
1310@1487978547.771234:vxhs_open_vdiskid Opening vdisk-id /test.raw
can't open device json:{"server.host": "127.0.0.1", "server.port":
"9999", "vdisk-id": "/test.raw", "driver": "vxhs"}: please specify the
user for authenticating to target

diff --git a/block/vxhs.c b/block/vxhs.c
index 4f0633e..9b60ddf 100644
--- a/block/vxhs.c
+++ b/block/vxhs.c
@@ -17,12 +17,16 @@
 #include "qemu/uri.h"
 #include "qapi/error.h"
 #include "qemu/uuid.h"
+#include "crypto/secret.h"

 #define VXHS_OPT_FILENAME           "filename"
 #define VXHS_OPT_VDISK_ID           "vdisk-id"
 #define VXHS_OPT_SERVER             "server"
 #define VXHS_OPT_HOST               "host"
 #define VXHS_OPT_PORT               "port"
+#define VXHS_OPT_USER               "user"
+#define VXHS_OPT_PASSWORD           "password"
+#define VXHS_OPT_SECRETID           "password-secret"
 #define VXHS_UUID_DEF "12345678-1234-1234-1234-123456789012"

 QemuUUID qemu_uuid __attribute__ ((weak));
@@ -136,6 +140,22 @@ static QemuOptsList runtime_opts = {
             .type = QEMU_OPT_STRING,
             .help = "UUID of the VxHS vdisk",
         },
+        {
+            .name = VXHS_OPT_USER,
+            .type = QEMU_OPT_STRING,
+            .help = "username for authentication to target",
+        },
+        {
+            .name = VXHS_OPT_PASSWORD,
+            .type = QEMU_OPT_STRING,
+            .help = "password for authentication to target",
+        },
+        {
+            .name = VXHS_OPT_SECRETID,
+            .type = QEMU_OPT_STRING,
+            .help = "ID of the secret providing password for"
+                    "authentication to target",
+        },
         { /* end of list */ }
     },
 };
@@ -257,6 +277,9 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     const char *server_host_opt;
     char *str = NULL;
     int ret = 0;
+    const char *user = NULL;
+    const char *secretid = NULL;
+    const char *password = NULL;

     ret = vxhs_init_and_ref();
     if (ret < 0) {
@@ -320,6 +343,35 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
         goto out;
     }

+    /* check if we got username and secretid via the options */
+    user = qemu_opt_get(opts, VXHS_OPT_USER);
+    if (!user) {
+        error_setg(&local_err, "please specify the user for authenticating to "
+                   "target");
+        qdict_del(backing_options, str);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    secretid = qemu_opt_get(opts, VXHS_OPT_SECRETID);
+    if (!secretid) {
+        error_setg(&local_err, "please specify the ID of the secret to be "
+                   "used for authenticating to target");
+        qdict_del(backing_options, str);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* check if we got password via the --object argument */
+    password = qcrypto_secret_lookup_as_utf8(secretid, &local_err);
+    if (local_err != NULL) {
+        trace_vxhs_get_creds(user, secretid, password);
+        qdict_del(backing_options, str);
+        ret = -EINVAL;
+        goto out;
+    }
+    trace_vxhs_get_creds(user, secretid, password);
+
     s->vdisk_hostinfo.host = g_strdup(server_host_opt);

     s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,

Regards,
Ashish


On Fri, Feb 24, 2017 at 1:19 AM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Thu, Feb 23, 2017 at 08:19:29PM -0800, ashish mittal wrote:
>> Hi,
>>
>> Just want to check if the following mechanism for accepting the secret
>> password looks OK?
>>
>> We have yet to internally discuss the semantics of how we plan to use
>> the user-ID/password for authentication. This diff is just to
>> understand how I am expected to accept the secret from the command
>> line.
>>
>> Example specifying the username and password:
>>
>> $ ./qemu-io --trace enable=vxhs* --object
>> secret,id=ashish,data=asd888d989s  -c 'read 66000 128k'
>> 'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
>> "/test.raw", "driver": "vxhs", "user": "ashish"}'
>> 17396@1487908905.546890:vxhs_open_vdiskid Opening vdisk-id /test.raw
>> 17396@1487908905.546969:vxhs_get_creds SecretID ashish, Password
>> asd888d989s   <==== NOTE!!!!!
>> 17396@1487908905.546994:vxhs_open_hostinfo Adding host 127.0.0.1:9999
>> to BDRVVXHSState
>> 17396@1487908905.568370:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
>> returned size 196616
>> read 131072/131072 bytes at offset 66000
>> 128 KiB, 1 ops; 0.0017 sec (72.844 MiB/sec and 582.7506 ops/sec)
>> 17396@1487908905.570917:vxhs_close Closing vdisk /test.raw
>> [root@rhel72ga-build-upstream qemu] 2017-02-23 20:01:45$
>>
>> Example where username and password are missing:
>>
>> [root@rhel72ga-build-upstream qemu] 2017-02-23 19:30:16$ ./qemu-io
>> --trace enable=vxhs* -c 'read 66000 128k' 'json:{"server.host":
>> "127.0.0.1", "server.port": "9999", "vdisk-id": "/test.raw", "driver":
>> "vxhs"}'
>> 16120@1487907025.251167:vxhs_open_vdiskid Opening vdisk-id /test.raw
>> 16120@1487907025.251245:vxhs_get_creds SecretID user, Password (null)
>> can't open device json:{"server.host": "127.0.0.1", "server.port":
>> "9999", "vdisk-id": "/test.raw", "driver": "vxhs"}: No secret with id
>> 'user'      <==== NOTE!!!!!
>> [root@rhel72ga-build-upstream qemu] 2017-02-23 19:30:25$
>
> It is close but not quite correct approach. You're overloading a
> single property to provide two different things - the username
> and as a key to lookup the password secret - you want different
> properties.
>
>
> The 'secret' object only needs to be used for data that must be
> kept private. By convention the block drivers try to use a property
> 'password-secret' to reference the ID of the secret object.
>
> So, as an example, if you had a username "fred" and passwd "letmein"
> then a suitable syntax would be
>
>  $ ./qemu-io \
>     --object secret,id=vxhspasswd,data=letmein
>     -c 'read 66000 128k'
>     'json:{"server.host": "127.0.0.1", "server.port": "9999",
>            "vdisk-id": "/test.raw", "driver": "vxhs",
>            "user": "fred", "password-secret": "xvxhspasswd"}'
>
> (obviously in real world, we'd not send across the password
> in clear text in the data= parameter of the secret - we'd
> use the file= parameter instead, but its fine for dev testing.
>
>> diff --git a/block/vxhs.c b/block/vxhs.c
>> index 4f0633e..f3e70ce 100644
>> --- a/block/vxhs.c
>> +++ b/block/vxhs.c
>> @@ -17,6 +17,7 @@
>>  #include "qemu/uri.h"
>>  #include "qapi/error.h"
>>  #include "qemu/uuid.h"
>> +#include "crypto/secret.h"
>>
>>  #define VXHS_OPT_FILENAME           "filename"
>>  #define VXHS_OPT_VDISK_ID           "vdisk-id"
>> @@ -136,6 +137,14 @@ static QemuOptsList runtime_opts = {
>>              .type = QEMU_OPT_STRING,
>>              .help = "UUID of the VxHS vdisk",
>>          },
>> +        {
>> +            .name = "user",
>> +            .type = QEMU_OPT_STRING,
>> +        },
>> +        {
>> +            .name = "password",
>> +            .type = QEMU_OPT_STRING,
>> +        },
>>          { /* end of list */ }
>>      },
>>  };
>> @@ -257,6 +266,8 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>>      const char *server_host_opt;
>>      char *str = NULL;
>>      int ret = 0;
>> +    const char *user = NULL;
>> +    const char *password = NULL;
>>
>>      ret = vxhs_init_and_ref();
>>      if (ret < 0) {
>> @@ -320,6 +331,23 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>>          goto out;
>>      }
>>
>> +    /* check if we got username via the options */
>> +    user = qemu_opt_get(opts, "user");
>> +    if (!user) {
>> +        //trace_vxhs_get_creds(user, password);
>> +        user = "user";
>
> We should not default any login credentials - if no username was
> provided we should simply not use any username - if the server
> mandates a username this obviously means connection would fail
> and that's ok.
>
>> +        //return;
>> +    }
>> +
>> +    password = qcrypto_secret_lookup_as_utf8(user, &local_err);
>
> Instead of passing 'user' into this method, you need to call
> qemu_opt_get(opts, "password-secret") and use that result
>
>> +    if (local_err != NULL) {
>> +        trace_vxhs_get_creds(user, password);
>> +        qdict_del(backing_options, str);
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +    trace_vxhs_get_creds(user, password);
>> +
>
> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-24  4:19                   ` ashish mittal
@ 2017-02-24  9:19                     ` Daniel P. Berrange
  2017-02-24 23:30                       ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-24  9:19 UTC (permalink / raw)
  To: ashish mittal
  Cc: Jeff Cody, Stefan Hajnoczi, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Thu, Feb 23, 2017 at 08:19:29PM -0800, ashish mittal wrote:
> Hi,
> 
> Just want to check if the following mechanism for accepting the secret
> password looks OK?
> 
> We have yet to internally discuss the semantics of how we plan to use
> the user-ID/password for authentication. This diff is just to
> understand how I am expected to accept the secret from the command
> line.
> 
> Example specifying the username and password:
> 
> $ ./qemu-io --trace enable=vxhs* --object
> secret,id=ashish,data=asd888d989s  -c 'read 66000 128k'
> 'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
> "/test.raw", "driver": "vxhs", "user": "ashish"}'
> 17396@1487908905.546890:vxhs_open_vdiskid Opening vdisk-id /test.raw
> 17396@1487908905.546969:vxhs_get_creds SecretID ashish, Password
> asd888d989s   <==== NOTE!!!!!
> 17396@1487908905.546994:vxhs_open_hostinfo Adding host 127.0.0.1:9999
> to BDRVVXHSState
> 17396@1487908905.568370:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
> returned size 196616
> read 131072/131072 bytes at offset 66000
> 128 KiB, 1 ops; 0.0017 sec (72.844 MiB/sec and 582.7506 ops/sec)
> 17396@1487908905.570917:vxhs_close Closing vdisk /test.raw
> [root@rhel72ga-build-upstream qemu] 2017-02-23 20:01:45$
> 
> Example where username and password are missing:
> 
> [root@rhel72ga-build-upstream qemu] 2017-02-23 19:30:16$ ./qemu-io
> --trace enable=vxhs* -c 'read 66000 128k' 'json:{"server.host":
> "127.0.0.1", "server.port": "9999", "vdisk-id": "/test.raw", "driver":
> "vxhs"}'
> 16120@1487907025.251167:vxhs_open_vdiskid Opening vdisk-id /test.raw
> 16120@1487907025.251245:vxhs_get_creds SecretID user, Password (null)
> can't open device json:{"server.host": "127.0.0.1", "server.port":
> "9999", "vdisk-id": "/test.raw", "driver": "vxhs"}: No secret with id
> 'user'      <==== NOTE!!!!!
> [root@rhel72ga-build-upstream qemu] 2017-02-23 19:30:25$

It is close but not quite correct approach. You're overloading a
single property to provide two different things - the username
and as a key to lookup the password secret - you want different
properties.


The 'secret' object only needs to be used for data that must be
kept private. By convention the block drivers try to use a property
'password-secret' to reference the ID of the secret object.

So, as an example, if you had a username "fred" and passwd "letmein"
then a suitable syntax would be

 $ ./qemu-io \
    --object secret,id=vxhspasswd,data=letmein
    -c 'read 66000 128k'
    'json:{"server.host": "127.0.0.1", "server.port": "9999",
           "vdisk-id": "/test.raw", "driver": "vxhs",
           "user": "fred", "password-secret": "xvxhspasswd"}'

(obviously in real world, we'd not send across the password
in clear text in the data= parameter of the secret - we'd
use the file= parameter instead, but its fine for dev testing.

> diff --git a/block/vxhs.c b/block/vxhs.c
> index 4f0633e..f3e70ce 100644
> --- a/block/vxhs.c
> +++ b/block/vxhs.c
> @@ -17,6 +17,7 @@
>  #include "qemu/uri.h"
>  #include "qapi/error.h"
>  #include "qemu/uuid.h"
> +#include "crypto/secret.h"
> 
>  #define VXHS_OPT_FILENAME           "filename"
>  #define VXHS_OPT_VDISK_ID           "vdisk-id"
> @@ -136,6 +137,14 @@ static QemuOptsList runtime_opts = {
>              .type = QEMU_OPT_STRING,
>              .help = "UUID of the VxHS vdisk",
>          },
> +        {
> +            .name = "user",
> +            .type = QEMU_OPT_STRING,
> +        },
> +        {
> +            .name = "password",
> +            .type = QEMU_OPT_STRING,
> +        },
>          { /* end of list */ }
>      },
>  };
> @@ -257,6 +266,8 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>      const char *server_host_opt;
>      char *str = NULL;
>      int ret = 0;
> +    const char *user = NULL;
> +    const char *password = NULL;
> 
>      ret = vxhs_init_and_ref();
>      if (ret < 0) {
> @@ -320,6 +331,23 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
>          goto out;
>      }
> 
> +    /* check if we got username via the options */
> +    user = qemu_opt_get(opts, "user");
> +    if (!user) {
> +        //trace_vxhs_get_creds(user, password);
> +        user = "user";

We should not default any login credentials - if no username was
provided we should simply not use any username - if the server
mandates a username this obviously means connection would fail
and that's ok.

> +        //return;
> +    }
> +
> +    password = qcrypto_secret_lookup_as_utf8(user, &local_err);

Instead of passing 'user' into this method, you need to call
qemu_opt_get(opts, "password-secret") and use that result

> +    if (local_err != NULL) {
> +        trace_vxhs_get_creds(user, password);
> +        qdict_del(backing_options, str);
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +    trace_vxhs_get_creds(user, password);
> +

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-22 14:44                 ` Jeff Cody
@ 2017-02-24  4:19                   ` ashish mittal
  2017-02-24  9:19                     ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-24  4:19 UTC (permalink / raw)
  To: Jeff Cody
  Cc: Daniel P. Berrange, Stefan Hajnoczi, Ketan Nilangekar,
	qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Fam Zheng, Ashish Mittal, John Ferlan, Buddhi Madhav,
	Suraj Singh, Nitin Jerath, Peter Maydell, Abhijit Dey,
	Venkatesha M.G.,
	Rakesh Ranjan

Hi,

Just want to check if the following mechanism for accepting the secret
password looks OK?

We have yet to internally discuss the semantics of how we plan to use
the user-ID/password for authentication. This diff is just to
understand how I am expected to accept the secret from the command
line.

Example specifying the username and password:

$ ./qemu-io --trace enable=vxhs* --object
secret,id=ashish,data=asd888d989s  -c 'read 66000 128k'
'json:{"server.host": "127.0.0.1", "server.port": "9999", "vdisk-id":
"/test.raw", "driver": "vxhs", "user": "ashish"}'
17396@1487908905.546890:vxhs_open_vdiskid Opening vdisk-id /test.raw
17396@1487908905.546969:vxhs_get_creds SecretID ashish, Password
asd888d989s   <==== NOTE!!!!!
17396@1487908905.546994:vxhs_open_hostinfo Adding host 127.0.0.1:9999
to BDRVVXHSState
17396@1487908905.568370:vxhs_get_vdisk_stat vDisk /test.raw stat ioctl
returned size 196616
read 131072/131072 bytes at offset 66000
128 KiB, 1 ops; 0.0017 sec (72.844 MiB/sec and 582.7506 ops/sec)
17396@1487908905.570917:vxhs_close Closing vdisk /test.raw
[root@rhel72ga-build-upstream qemu] 2017-02-23 20:01:45$

Example where username and password are missing:

[root@rhel72ga-build-upstream qemu] 2017-02-23 19:30:16$ ./qemu-io
--trace enable=vxhs* -c 'read 66000 128k' 'json:{"server.host":
"127.0.0.1", "server.port": "9999", "vdisk-id": "/test.raw", "driver":
"vxhs"}'
16120@1487907025.251167:vxhs_open_vdiskid Opening vdisk-id /test.raw
16120@1487907025.251245:vxhs_get_creds SecretID user, Password (null)
can't open device json:{"server.host": "127.0.0.1", "server.port":
"9999", "vdisk-id": "/test.raw", "driver": "vxhs"}: No secret with id
'user'      <==== NOTE!!!!!
[root@rhel72ga-build-upstream qemu] 2017-02-23 19:30:25$


diff --git a/block/vxhs.c b/block/vxhs.c
index 4f0633e..f3e70ce 100644
--- a/block/vxhs.c
+++ b/block/vxhs.c
@@ -17,6 +17,7 @@
 #include "qemu/uri.h"
 #include "qapi/error.h"
 #include "qemu/uuid.h"
+#include "crypto/secret.h"

 #define VXHS_OPT_FILENAME           "filename"
 #define VXHS_OPT_VDISK_ID           "vdisk-id"
@@ -136,6 +137,14 @@ static QemuOptsList runtime_opts = {
             .type = QEMU_OPT_STRING,
             .help = "UUID of the VxHS vdisk",
         },
+        {
+            .name = "user",
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = "password",
+            .type = QEMU_OPT_STRING,
+        },
         { /* end of list */ }
     },
 };
@@ -257,6 +266,8 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
     const char *server_host_opt;
     char *str = NULL;
     int ret = 0;
+    const char *user = NULL;
+    const char *password = NULL;

     ret = vxhs_init_and_ref();
     if (ret < 0) {
@@ -320,6 +331,23 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
         goto out;
     }

+    /* check if we got username via the options */
+    user = qemu_opt_get(opts, "user");
+    if (!user) {
+        //trace_vxhs_get_creds(user, password);
+        user = "user";
+        //return;
+    }
+
+    password = qcrypto_secret_lookup_as_utf8(user, &local_err);
+    if (local_err != NULL) {
+        trace_vxhs_get_creds(user, password);
+        qdict_del(backing_options, str);
+        ret = -EINVAL;
+        goto out;
+    }
+    trace_vxhs_get_creds(user, password);
+
     s->vdisk_hostinfo.host = g_strdup(server_host_opt);

     s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,

Thanks,
Ashish

On Wed, Feb 22, 2017 at 6:44 AM, Jeff Cody <jcody@redhat.com> wrote:
> On Wed, Feb 22, 2017 at 02:22:30PM +0000, Daniel P. Berrange wrote:
>> On Wed, Feb 22, 2017 at 02:09:20PM +0000, Stefan Hajnoczi wrote:
>> > On Tue, Feb 21, 2017 at 11:33:53AM +0000, Daniel P. Berrange wrote:
>> > > On Tue, Feb 21, 2017 at 10:59:18AM +0000, Stefan Hajnoczi wrote:
>> > > > On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
>> > > > > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
>> > > > > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
>> > > > > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
>> > > > > >>
>> > > > > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
>> > > > > >>     > Hi,
>> > > > > >>     >
>> > > > > >>     > I am getting the following error with checkpatch.pl
>> > > > > >>     >
>> > > > > >>     > ERROR: externs should be avoided in .c files
>> > > > > >>     > #78: FILE: block/vxhs.c:28:
>> > > > > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
>> > > > > >>     >
>> > > > > >>     > Is there any way to get around this, or does it mean that I would have
>> > > > > >>     > to add a vxhs.h just for this one entry?
>> > > > > >>     >
>> > > > > >>
>> > > > > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
>> > > > > >>     cert.
>> > > > > >>
>> > > > > >> [ketan]
>> > > > > >> Is there another identity that can be used for uniquely identifying instances?
>> > > > > >> The requirement was to enforce vdisk access to owner instances.
>> > > > > >
>> > > > > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
>> > > > > > strong qemu_uuid symbol?
>> > > > > >
>> > > > > > Why aren't configuration parameters like the UUID coming from the QEMU
>> > > > > > command-line?
>> > > > > >
>> > > > > > Stefan
>> > > > >
>> > > > > UUID will in fact come from the QEMU command line. VxHS is not doing
>> > > > > anything special here. It will just use the value already available to
>> > > > > qemu-kvm process.
>> > > > >
>> > > > > QemuUUID qemu_uuid;
>> > > > > bool qemu_uuid_set;
>> > > > >
>> > > > > Both the above are defined in vl.c. vl.c will provide the strong
>> > > > > symbol when available. There are certain binaries that do not get
>> > > > > linked with vl.c (e.g. qemu-img). The weak symbol will come into
>> > > > > affect for such binaries, and in this case, the default VXHS UUID will
>> > > > > get picked up. I had, in a previous email, explained how we plan to
>> > > > > use the default UUID. In the regular case, the VxHS controller will
>> > > > > not allow access to the default UUID (non qemu-kvm) binaries, but it
>> > > > > may choose to grant temporary access to specific vdisks for these
>> > > > > binaries depending on the workflow.
>> > > >
>> > > > That idea sounds like a security problem.  During this time window
>> > > > anyone could use the default UUID to access the data?
>> > >
>> > > Any use of the VM UUID as a means to control authorization on the
>> > > server side is a security flaw, as this is a public value which
>> > > cannot be trusted on its own.
>> > >
>> > > There needs to be some kind of authentication step to verify the
>> > > reported identity, eg a password associated with the VM UUID that
>> > > is validated before trusting the VM UUID.
>> > >
>> > > Alternatively there needs to be a completely separate UUID, unrelated
>> > > to the VM UUID, which is treated as a private value (eg uses the
>> > > '-object secret' framework in QEMU)
>> >
>> > I thought the UUID is used to select the TLS client certificate and
>> > associated private key.  So the UUID provides authorization although
>> > what really matters is the client certificate, not the actual value of
>> > the UUID.
>>
>> The message shown a few replies earlier said:
>>
>>   "VxHS controller will not allow access to the default UUID (non qemu-kvm)
>>    binaries, but it may choose to grant temporary access to specific
>>    vdisks"
>>
>> which suggests the VxHS server is making authorization decisions based
>> on UUID, but perhaps this is incorrect interpretation and it really is
>> making decisions based on the x509 cert identity or something else ?
>>
>>
>> In any case hardcoding a policy of using the UUID to select a cert path
>> is a flawed design. We can't assume that everyone deploying QEMU is going
>> to be willing to configure a separate certificate per QEMU VM instance
>> launched. People's CA management policies are often so burdensome that
>> it will be impractical to generate a new cert for VMs on the fly. So we
>> should expect that many people will just deploy one cert per host, with
>> the cert being statically created at the time they setup the host. Thus
>> we need to just be able to specify certs used explicitly when adding a
>> disk to QEMU, so we can support different deployment models for cert
>> usage
>>
>
> I do believe it is using the UUID to select the cert/key files; from
> libqnio:
>
> https://github.com/VeritasHyperScale/libqnio/blob/securify/src/lib/qnio/utils.c#L81
>
> That instanceid is the UUID passed in during the initial call to iio_init().
>
> Also, does QEMU make any promises about qemu_uuid either being 0 or
> undefined for qemu-img and qemu-io in the future?  If that assumption
> changes in the future, it would also break the scheme in the these patches.
>
> -Jeff

^ permalink raw reply related	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-22 14:22               ` Daniel P. Berrange
@ 2017-02-22 14:44                 ` Jeff Cody
  2017-02-24  4:19                   ` ashish mittal
  0 siblings, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-22 14:44 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Stefan Hajnoczi, ashish mittal, Ketan Nilangekar, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Feb 22, 2017 at 02:22:30PM +0000, Daniel P. Berrange wrote:
> On Wed, Feb 22, 2017 at 02:09:20PM +0000, Stefan Hajnoczi wrote:
> > On Tue, Feb 21, 2017 at 11:33:53AM +0000, Daniel P. Berrange wrote:
> > > On Tue, Feb 21, 2017 at 10:59:18AM +0000, Stefan Hajnoczi wrote:
> > > > On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > > > > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > > > > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > > > > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > > > > >>
> > > > > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > > > > >>     > Hi,
> > > > > >>     >
> > > > > >>     > I am getting the following error with checkpatch.pl
> > > > > >>     >
> > > > > >>     > ERROR: externs should be avoided in .c files
> > > > > >>     > #78: FILE: block/vxhs.c:28:
> > > > > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > > > > >>     >
> > > > > >>     > Is there any way to get around this, or does it mean that I would have
> > > > > >>     > to add a vxhs.h just for this one entry?
> > > > > >>     >
> > > > > >>
> > > > > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > > > > >>     cert.
> > > > > >>
> > > > > >> [ketan]
> > > > > >> Is there another identity that can be used for uniquely identifying instances?
> > > > > >> The requirement was to enforce vdisk access to owner instances.
> > > > > >
> > > > > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > > > > > strong qemu_uuid symbol?
> > > > > >
> > > > > > Why aren't configuration parameters like the UUID coming from the QEMU
> > > > > > command-line?
> > > > > >
> > > > > > Stefan
> > > > > 
> > > > > UUID will in fact come from the QEMU command line. VxHS is not doing
> > > > > anything special here. It will just use the value already available to
> > > > > qemu-kvm process.
> > > > > 
> > > > > QemuUUID qemu_uuid;
> > > > > bool qemu_uuid_set;
> > > > > 
> > > > > Both the above are defined in vl.c. vl.c will provide the strong
> > > > > symbol when available. There are certain binaries that do not get
> > > > > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > > > > affect for such binaries, and in this case, the default VXHS UUID will
> > > > > get picked up. I had, in a previous email, explained how we plan to
> > > > > use the default UUID. In the regular case, the VxHS controller will
> > > > > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > > > > may choose to grant temporary access to specific vdisks for these
> > > > > binaries depending on the workflow.
> > > > 
> > > > That idea sounds like a security problem.  During this time window
> > > > anyone could use the default UUID to access the data?
> > > 
> > > Any use of the VM UUID as a means to control authorization on the
> > > server side is a security flaw, as this is a public value which
> > > cannot be trusted on its own.
> > > 
> > > There needs to be some kind of authentication step to verify the
> > > reported identity, eg a password associated with the VM UUID that
> > > is validated before trusting the VM UUID.
> > > 
> > > Alternatively there needs to be a completely separate UUID, unrelated
> > > to the VM UUID, which is treated as a private value (eg uses the
> > > '-object secret' framework in QEMU)
> > 
> > I thought the UUID is used to select the TLS client certificate and
> > associated private key.  So the UUID provides authorization although
> > what really matters is the client certificate, not the actual value of
> > the UUID.
> 
> The message shown a few replies earlier said:
> 
>   "VxHS controller will not allow access to the default UUID (non qemu-kvm)
>    binaries, but it may choose to grant temporary access to specific
>    vdisks"
> 
> which suggests the VxHS server is making authorization decisions based
> on UUID, but perhaps this is incorrect interpretation and it really is
> making decisions based on the x509 cert identity or something else ?
> 
> 
> In any case hardcoding a policy of using the UUID to select a cert path
> is a flawed design. We can't assume that everyone deploying QEMU is going
> to be willing to configure a separate certificate per QEMU VM instance
> launched. People's CA management policies are often so burdensome that
> it will be impractical to generate a new cert for VMs on the fly. So we
> should expect that many people will just deploy one cert per host, with
> the cert being statically created at the time they setup the host. Thus
> we need to just be able to specify certs used explicitly when adding a
> disk to QEMU, so we can support different deployment models for cert
> usage
>

I do believe it is using the UUID to select the cert/key files; from
libqnio:

https://github.com/VeritasHyperScale/libqnio/blob/securify/src/lib/qnio/utils.c#L81

That instanceid is the UUID passed in during the initial call to iio_init().

Also, does QEMU make any promises about qemu_uuid either being 0 or
undefined for qemu-img and qemu-io in the future?  If that assumption
changes in the future, it would also break the scheme in the these patches.

-Jeff

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 17:21           ` Ketan Nilangekar
  2017-02-21 17:39             ` Daniel P. Berrange
@ 2017-02-22 14:25             ` Stefan Hajnoczi
  1 sibling, 0 replies; 56+ messages in thread
From: Stefan Hajnoczi @ 2017-02-22 14:25 UTC (permalink / raw)
  To: Ketan Nilangekar
  Cc: ashish mittal, Jeff Cody, qemu-devel, Paolo Bonzini, Kevin Wolf,
	Markus Armbruster, Daniel P. Berrange, Fam Zheng, Ashish Mittal,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

[-- Attachment #1: Type: text/plain, Size: 3704 bytes --]

On Tue, Feb 21, 2017 at 05:21:46PM +0000, Ketan Nilangekar wrote:
> 
> 
> On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:
> 
>     On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
>     > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
>     > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
>     > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
>     > >>
>     > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
>     > >>     > Hi,
>     > >>     >
>     > >>     > I am getting the following error with checkpatch.pl
>     > >>     >
>     > >>     > ERROR: externs should be avoided in .c files
>     > >>     > #78: FILE: block/vxhs.c:28:
>     > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
>     > >>     >
>     > >>     > Is there any way to get around this, or does it mean that I would have
>     > >>     > to add a vxhs.h just for this one entry?
>     > >>     >
>     > >>
>     > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
>     > >>     cert.
>     > >>
>     > >> [ketan]
>     > >> Is there another identity that can be used for uniquely identifying instances?
>     > >> The requirement was to enforce vdisk access to owner instances.
>     > >
>     > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
>     > > strong qemu_uuid symbol?
>     > >
>     > > Why aren't configuration parameters like the UUID coming from the QEMU
>     > > command-line?
>     > >
>     > > Stefan
>     > 
>     > UUID will in fact come from the QEMU command line. VxHS is not doing
>     > anything special here. It will just use the value already available to
>     > qemu-kvm process.
>     > 
>     > QemuUUID qemu_uuid;
>     > bool qemu_uuid_set;
>     > 
>     > Both the above are defined in vl.c. vl.c will provide the strong
>     > symbol when available. There are certain binaries that do not get
>     > linked with vl.c (e.g. qemu-img). The weak symbol will come into
>     > affect for such binaries, and in this case, the default VXHS UUID will
>     > get picked up. I had, in a previous email, explained how we plan to
>     > use the default UUID. In the regular case, the VxHS controller will
>     > not allow access to the default UUID (non qemu-kvm) binaries, but it
>     > may choose to grant temporary access to specific vdisks for these
>     > binaries depending on the workflow.
>     
>     That idea sounds like a security problem.  During this time window
>     anyone could use the default UUID to access the data?
>     
>     Just make the UUID (or TLS client certificate file) a command-line
>     parameter that qemu-system, qemu-img, and other tools accept (e.g.
>     qemu-img via the --image-opts/--object syntax).
>     
> [Ketan]
> Sounds fair. Would it be ok to take this up after the driver is merged for the upcoming QEMU release?

No, because the current command-line interface isn't production-ready.
QEMU's command-line interface must stay backwards compatible forever so
merging the incomplete code now will create problems.

Start by tackling the comments that Daniel Berrange made 9 days ago
about hardcoded paths in libvxhs:
https://github.com/VeritasHyperScale/libqnio/pull/12#discussion_r100812640

As a consequence of resolving that issue, the QEMU block driver will
need new command-line parameters so it can pass in the configuration.
Then qemu_uuid will not be needed anymore because the command-line
parameters should already specify everything that libvxhs needs.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-22 14:09             ` Stefan Hajnoczi
@ 2017-02-22 14:22               ` Daniel P. Berrange
  2017-02-22 14:44                 ` Jeff Cody
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-22 14:22 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: ashish mittal, Ketan Nilangekar, Jeff Cody, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Wed, Feb 22, 2017 at 02:09:20PM +0000, Stefan Hajnoczi wrote:
> On Tue, Feb 21, 2017 at 11:33:53AM +0000, Daniel P. Berrange wrote:
> > On Tue, Feb 21, 2017 at 10:59:18AM +0000, Stefan Hajnoczi wrote:
> > > On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > > > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > > > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > > > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > > > >>
> > > > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > > > >>     > Hi,
> > > > >>     >
> > > > >>     > I am getting the following error with checkpatch.pl
> > > > >>     >
> > > > >>     > ERROR: externs should be avoided in .c files
> > > > >>     > #78: FILE: block/vxhs.c:28:
> > > > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > > > >>     >
> > > > >>     > Is there any way to get around this, or does it mean that I would have
> > > > >>     > to add a vxhs.h just for this one entry?
> > > > >>     >
> > > > >>
> > > > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > > > >>     cert.
> > > > >>
> > > > >> [ketan]
> > > > >> Is there another identity that can be used for uniquely identifying instances?
> > > > >> The requirement was to enforce vdisk access to owner instances.
> > > > >
> > > > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > > > > strong qemu_uuid symbol?
> > > > >
> > > > > Why aren't configuration parameters like the UUID coming from the QEMU
> > > > > command-line?
> > > > >
> > > > > Stefan
> > > > 
> > > > UUID will in fact come from the QEMU command line. VxHS is not doing
> > > > anything special here. It will just use the value already available to
> > > > qemu-kvm process.
> > > > 
> > > > QemuUUID qemu_uuid;
> > > > bool qemu_uuid_set;
> > > > 
> > > > Both the above are defined in vl.c. vl.c will provide the strong
> > > > symbol when available. There are certain binaries that do not get
> > > > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > > > affect for such binaries, and in this case, the default VXHS UUID will
> > > > get picked up. I had, in a previous email, explained how we plan to
> > > > use the default UUID. In the regular case, the VxHS controller will
> > > > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > > > may choose to grant temporary access to specific vdisks for these
> > > > binaries depending on the workflow.
> > > 
> > > That idea sounds like a security problem.  During this time window
> > > anyone could use the default UUID to access the data?
> > 
> > Any use of the VM UUID as a means to control authorization on the
> > server side is a security flaw, as this is a public value which
> > cannot be trusted on its own.
> > 
> > There needs to be some kind of authentication step to verify the
> > reported identity, eg a password associated with the VM UUID that
> > is validated before trusting the VM UUID.
> > 
> > Alternatively there needs to be a completely separate UUID, unrelated
> > to the VM UUID, which is treated as a private value (eg uses the
> > '-object secret' framework in QEMU)
> 
> I thought the UUID is used to select the TLS client certificate and
> associated private key.  So the UUID provides authorization although
> what really matters is the client certificate, not the actual value of
> the UUID.

The message shown a few replies earlier said:

  "VxHS controller will not allow access to the default UUID (non qemu-kvm)
   binaries, but it may choose to grant temporary access to specific
   vdisks"

which suggests the VxHS server is making authorization decisions based
on UUID, but perhaps this is incorrect interpretation and it really is
making decisions based on the x509 cert identity or something else ?


In any case hardcoding a policy of using the UUID to select a cert path
is a flawed design. We can't assume that everyone deploying QEMU is going
to be willing to configure a separate certificate per QEMU VM instance
launched. People's CA management policies are often so burdensome that
it will be impractical to generate a new cert for VMs on the fly. So we
should expect that many people will just deploy one cert per host, with
the cert being statically created at the time they setup the host. Thus
we need to just be able to specify certs used explicitly when adding a
disk to QEMU, so we can support different deployment models for cert
usage

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 11:33           ` Daniel P. Berrange
@ 2017-02-22 14:09             ` Stefan Hajnoczi
  2017-02-22 14:22               ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: Stefan Hajnoczi @ 2017-02-22 14:09 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: ashish mittal, Ketan Nilangekar, Jeff Cody, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

[-- Attachment #1: Type: text/plain, Size: 3359 bytes --]

On Tue, Feb 21, 2017 at 11:33:53AM +0000, Daniel P. Berrange wrote:
> On Tue, Feb 21, 2017 at 10:59:18AM +0000, Stefan Hajnoczi wrote:
> > On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > > >>
> > > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > > >>     > Hi,
> > > >>     >
> > > >>     > I am getting the following error with checkpatch.pl
> > > >>     >
> > > >>     > ERROR: externs should be avoided in .c files
> > > >>     > #78: FILE: block/vxhs.c:28:
> > > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > > >>     >
> > > >>     > Is there any way to get around this, or does it mean that I would have
> > > >>     > to add a vxhs.h just for this one entry?
> > > >>     >
> > > >>
> > > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > > >>     cert.
> > > >>
> > > >> [ketan]
> > > >> Is there another identity that can be used for uniquely identifying instances?
> > > >> The requirement was to enforce vdisk access to owner instances.
> > > >
> > > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > > > strong qemu_uuid symbol?
> > > >
> > > > Why aren't configuration parameters like the UUID coming from the QEMU
> > > > command-line?
> > > >
> > > > Stefan
> > > 
> > > UUID will in fact come from the QEMU command line. VxHS is not doing
> > > anything special here. It will just use the value already available to
> > > qemu-kvm process.
> > > 
> > > QemuUUID qemu_uuid;
> > > bool qemu_uuid_set;
> > > 
> > > Both the above are defined in vl.c. vl.c will provide the strong
> > > symbol when available. There are certain binaries that do not get
> > > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > > affect for such binaries, and in this case, the default VXHS UUID will
> > > get picked up. I had, in a previous email, explained how we plan to
> > > use the default UUID. In the regular case, the VxHS controller will
> > > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > > may choose to grant temporary access to specific vdisks for these
> > > binaries depending on the workflow.
> > 
> > That idea sounds like a security problem.  During this time window
> > anyone could use the default UUID to access the data?
> 
> Any use of the VM UUID as a means to control authorization on the
> server side is a security flaw, as this is a public value which
> cannot be trusted on its own.
> 
> There needs to be some kind of authentication step to verify the
> reported identity, eg a password associated with the VM UUID that
> is validated before trusting the VM UUID.
> 
> Alternatively there needs to be a completely separate UUID, unrelated
> to the VM UUID, which is treated as a private value (eg uses the
> '-object secret' framework in QEMU)

I thought the UUID is used to select the TLS client certificate and
associated private key.  So the UUID provides authorization although
what really matters is the client certificate, not the actual value of
the UUID.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 19:25                   ` Jeff Cody
@ 2017-02-22 10:12                     ` Daniel P. Berrange
  0 siblings, 0 replies; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-22 10:12 UTC (permalink / raw)
  To: Jeff Cody
  Cc: Ketan Nilangekar, Stefan Hajnoczi, ashish mittal, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 21, 2017 at 02:25:53PM -0500, Jeff Cody wrote:
> On Tue, Feb 21, 2017 at 06:56:24PM +0000, Daniel P. Berrange wrote:
> > On Tue, Feb 21, 2017 at 01:06:58PM -0500, Jeff Cody wrote:
> > > On Tue, Feb 21, 2017 at 05:39:12PM +0000, Daniel P. Berrange wrote:
> > > > On Tue, Feb 21, 2017 at 05:21:46PM +0000, Ketan Nilangekar wrote:
> > > > > 
> > > > > 
> > > > > On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:
> > > > > 
> > > > >     On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > > > >     > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > > > >     > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > > > >     > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > > > >     > >>
> > > > >     > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > > > >     > >>     > Hi,
> > > > >     > >>     >
> > > > >     > >>     > I am getting the following error with checkpatch.pl
> > > > >     > >>     >
> > > > >     > >>     > ERROR: externs should be avoided in .c files
> > > > >     > >>     > #78: FILE: block/vxhs.c:28:
> > > > >     > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > > > >     > >>     >
> > > > >     > >>     > Is there any way to get around this, or does it mean that I would have
> > > > >     > >>     > to add a vxhs.h just for this one entry?
> > > > >     > >>     >
> > > > >     > >>
> > > > >     > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > > > >     > >>     cert.
> > > > >     > >>
> > > > >     > >> [ketan]
> > > > >     > >> Is there another identity that can be used for uniquely identifying instances?
> > > > >     > >> The requirement was to enforce vdisk access to owner instances.
> > > > >     > >
> > > > >     > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > > > >     > > strong qemu_uuid symbol?
> > > > >     > >
> > > > >     > > Why aren't configuration parameters like the UUID coming from the QEMU
> > > > >     > > command-line?
> > > > >     > >
> > > > >     > > Stefan
> > > > >     > 
> > > > >     > UUID will in fact come from the QEMU command line. VxHS is not doing
> > > > >     > anything special here. It will just use the value already available to
> > > > >     > qemu-kvm process.
> > > > >     > 
> > > > >     > QemuUUID qemu_uuid;
> > > > >     > bool qemu_uuid_set;
> > > > >     > 
> > > > >     > Both the above are defined in vl.c. vl.c will provide the strong
> > > > >     > symbol when available. There are certain binaries that do not get
> > > > >     > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > > > >     > affect for such binaries, and in this case, the default VXHS UUID will
> > > > >     > get picked up. I had, in a previous email, explained how we plan to
> > > > >     > use the default UUID. In the regular case, the VxHS controller will
> > > > >     > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > > > >     > may choose to grant temporary access to specific vdisks for these
> > > > >     > binaries depending on the workflow.
> > > > >     
> > > > >     That idea sounds like a security problem.  During this time window
> > > > >     anyone could use the default UUID to access the data?
> > > > >     
> > > > >     Just make the UUID (or TLS client certificate file) a command-line
> > > > >     parameter that qemu-system, qemu-img, and other tools accept (e.g.
> > > > >     qemu-img via the --image-opts/--object syntax).
> > > > >     
> > > > > [Ketan]
> > > > > Sounds fair. Would it be ok to take this up after the driver is
> > > > > merged for the upcoming QEMU release?
> > > > 
> > > > I don't think we can merge code with known security flaws, particularly
> > > > if fixing these flaws will involve adding and/or changing command line
> > > > parameters for the block driver.
> > > >
> > > 
> > > We do support some protocols, such as gluster, that do not have robust
> > > authentication frameworks over tcp/ip.  Of course, these protocols have been
> > > in as a driver for several years (and, gluster does support unix sockets).
> > 
> > NB, gluster *does* have secure access control. It uses the verified x509
> > certificate identity as a token against which access control rules are
> > placed on volumes.
> > 
> > It isn't authentication in the traditional sense most people think of it,
> > but it does provide a secure authorization facility.
> >
> 
> Good point, thanks for the clarification.
> 
> > > We seem to be establishing a rule for QEMU, that is "no new protocol drivers
> > > without secure authentication".  That is a good thing. The existence of
> > > current protocol drivers that don't meet that criteria is potentially
> > > confusing for new contributors, however.  (As a side note to myself -- this
> > > is probably a good thing to add to the wiki, if it is not there already).
> > 
> > It's been my goal to fix / enhance everything in QEMU that uses network and
> > does not have secure encryption + access control facilities. eg by adding
> > TLS support to the NBD driver, and providing the secure mechanism for feeding
> > passwords into QEMU for things like curl, iscsi, etc. We're getting pretty
> > close to having at least the option to use encryption + access control via
> > TLS certs or SASL on every key network based feature in QEMU.
> > 
> > > I think a non-secure scheme is worse than no scheme at all, because it
> > > becomes relied upon and promises something it cannot deliver.  In that vein,
> > > would you object to a vxhs protocol driver that did no authentication at all
> > > (similar to gluster), or do you think the above rule is a new hard rule for
> > > protocol drivers?
> > 
> > Adding support for a known insecure authentication scheme is a clear
> > no-go as that's pretty much immediate CVE terrority when we release it,
> > as you give people the illusion of security where none exists.
> > 
> > IMHO, any new network protocol that we add to QEMU should at least be
> > capable of having secure encryption & access control enabled, unless it
> > is a long term pre-existing standard - even those have pretty much all
> > been given strong security extensions over the years as it became clear
> > that internal networks are often just as hostile as public networks.
> > eg the work we did to add TLS to VNC in 2007, or more recently adding
> > TLS to NBD. SPICE by constrast as a modern protocol had TLS right from
> > the start.
> > 
> 
> Thanks again.  I am in agreement with you.  It is probably a good idea to
> consider that "codified" now for new protocol drivers, to remove any
> ambiguity in the future - and the x509 certificate method should not be too
> difficult to implement.

FWIW, while x509 certificates do provide a secure identity for a client, it
is not the most flexible of things to work with. ie While you certainly can
deploy a separate x509 certificate for each QEMU, giving you a per-VM
identity, IME, most deployments will actually go for a one certificate
per host model. So if per-VM identity is very important, it can be beneficial
to have alternate identity & authorization mechanisms available. Of course
having multiple auth mechanisms shouldn't be a requirement from QEMU POV -
just one secure mechanism is sufficient to be acceptable for merge.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 18:56                 ` Daniel P. Berrange
@ 2017-02-21 19:25                   ` Jeff Cody
  2017-02-22 10:12                     ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-21 19:25 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Ketan Nilangekar, Stefan Hajnoczi, ashish mittal, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 21, 2017 at 06:56:24PM +0000, Daniel P. Berrange wrote:
> On Tue, Feb 21, 2017 at 01:06:58PM -0500, Jeff Cody wrote:
> > On Tue, Feb 21, 2017 at 05:39:12PM +0000, Daniel P. Berrange wrote:
> > > On Tue, Feb 21, 2017 at 05:21:46PM +0000, Ketan Nilangekar wrote:
> > > > 
> > > > 
> > > > On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:
> > > > 
> > > >     On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > > >     > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > > >     > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > > >     > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > > >     > >>
> > > >     > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > > >     > >>     > Hi,
> > > >     > >>     >
> > > >     > >>     > I am getting the following error with checkpatch.pl
> > > >     > >>     >
> > > >     > >>     > ERROR: externs should be avoided in .c files
> > > >     > >>     > #78: FILE: block/vxhs.c:28:
> > > >     > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > > >     > >>     >
> > > >     > >>     > Is there any way to get around this, or does it mean that I would have
> > > >     > >>     > to add a vxhs.h just for this one entry?
> > > >     > >>     >
> > > >     > >>
> > > >     > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > > >     > >>     cert.
> > > >     > >>
> > > >     > >> [ketan]
> > > >     > >> Is there another identity that can be used for uniquely identifying instances?
> > > >     > >> The requirement was to enforce vdisk access to owner instances.
> > > >     > >
> > > >     > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > > >     > > strong qemu_uuid symbol?
> > > >     > >
> > > >     > > Why aren't configuration parameters like the UUID coming from the QEMU
> > > >     > > command-line?
> > > >     > >
> > > >     > > Stefan
> > > >     > 
> > > >     > UUID will in fact come from the QEMU command line. VxHS is not doing
> > > >     > anything special here. It will just use the value already available to
> > > >     > qemu-kvm process.
> > > >     > 
> > > >     > QemuUUID qemu_uuid;
> > > >     > bool qemu_uuid_set;
> > > >     > 
> > > >     > Both the above are defined in vl.c. vl.c will provide the strong
> > > >     > symbol when available. There are certain binaries that do not get
> > > >     > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > > >     > affect for such binaries, and in this case, the default VXHS UUID will
> > > >     > get picked up. I had, in a previous email, explained how we plan to
> > > >     > use the default UUID. In the regular case, the VxHS controller will
> > > >     > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > > >     > may choose to grant temporary access to specific vdisks for these
> > > >     > binaries depending on the workflow.
> > > >     
> > > >     That idea sounds like a security problem.  During this time window
> > > >     anyone could use the default UUID to access the data?
> > > >     
> > > >     Just make the UUID (or TLS client certificate file) a command-line
> > > >     parameter that qemu-system, qemu-img, and other tools accept (e.g.
> > > >     qemu-img via the --image-opts/--object syntax).
> > > >     
> > > > [Ketan]
> > > > Sounds fair. Would it be ok to take this up after the driver is
> > > > merged for the upcoming QEMU release?
> > > 
> > > I don't think we can merge code with known security flaws, particularly
> > > if fixing these flaws will involve adding and/or changing command line
> > > parameters for the block driver.
> > >
> > 
> > We do support some protocols, such as gluster, that do not have robust
> > authentication frameworks over tcp/ip.  Of course, these protocols have been
> > in as a driver for several years (and, gluster does support unix sockets).
> 
> NB, gluster *does* have secure access control. It uses the verified x509
> certificate identity as a token against which access control rules are
> placed on volumes.
> 
> It isn't authentication in the traditional sense most people think of it,
> but it does provide a secure authorization facility.
>

Good point, thanks for the clarification.

> > We seem to be establishing a rule for QEMU, that is "no new protocol drivers
> > without secure authentication".  That is a good thing. The existence of
> > current protocol drivers that don't meet that criteria is potentially
> > confusing for new contributors, however.  (As a side note to myself -- this
> > is probably a good thing to add to the wiki, if it is not there already).
> 
> It's been my goal to fix / enhance everything in QEMU that uses network and
> does not have secure encryption + access control facilities. eg by adding
> TLS support to the NBD driver, and providing the secure mechanism for feeding
> passwords into QEMU for things like curl, iscsi, etc. We're getting pretty
> close to having at least the option to use encryption + access control via
> TLS certs or SASL on every key network based feature in QEMU.
> 
> > I think a non-secure scheme is worse than no scheme at all, because it
> > becomes relied upon and promises something it cannot deliver.  In that vein,
> > would you object to a vxhs protocol driver that did no authentication at all
> > (similar to gluster), or do you think the above rule is a new hard rule for
> > protocol drivers?
> 
> Adding support for a known insecure authentication scheme is a clear
> no-go as that's pretty much immediate CVE terrority when we release it,
> as you give people the illusion of security where none exists.
> 
> IMHO, any new network protocol that we add to QEMU should at least be
> capable of having secure encryption & access control enabled, unless it
> is a long term pre-existing standard - even those have pretty much all
> been given strong security extensions over the years as it became clear
> that internal networks are often just as hostile as public networks.
> eg the work we did to add TLS to VNC in 2007, or more recently adding
> TLS to NBD. SPICE by constrast as a modern protocol had TLS right from
> the start.
> 

Thanks again.  I am in agreement with you.  It is probably a good idea to
consider that "codified" now for new protocol drivers, to remove any
ambiguity in the future - and the x509 certificate method should not be too
difficult to implement.

-Jeff

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 18:06               ` Jeff Cody
@ 2017-02-21 18:56                 ` Daniel P. Berrange
  2017-02-21 19:25                   ` Jeff Cody
  0 siblings, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-21 18:56 UTC (permalink / raw)
  To: Jeff Cody
  Cc: Ketan Nilangekar, Stefan Hajnoczi, ashish mittal, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 21, 2017 at 01:06:58PM -0500, Jeff Cody wrote:
> On Tue, Feb 21, 2017 at 05:39:12PM +0000, Daniel P. Berrange wrote:
> > On Tue, Feb 21, 2017 at 05:21:46PM +0000, Ketan Nilangekar wrote:
> > > 
> > > 
> > > On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:
> > > 
> > >     On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > >     > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > >     > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > >     > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > >     > >>
> > >     > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > >     > >>     > Hi,
> > >     > >>     >
> > >     > >>     > I am getting the following error with checkpatch.pl
> > >     > >>     >
> > >     > >>     > ERROR: externs should be avoided in .c files
> > >     > >>     > #78: FILE: block/vxhs.c:28:
> > >     > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > >     > >>     >
> > >     > >>     > Is there any way to get around this, or does it mean that I would have
> > >     > >>     > to add a vxhs.h just for this one entry?
> > >     > >>     >
> > >     > >>
> > >     > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > >     > >>     cert.
> > >     > >>
> > >     > >> [ketan]
> > >     > >> Is there another identity that can be used for uniquely identifying instances?
> > >     > >> The requirement was to enforce vdisk access to owner instances.
> > >     > >
> > >     > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > >     > > strong qemu_uuid symbol?
> > >     > >
> > >     > > Why aren't configuration parameters like the UUID coming from the QEMU
> > >     > > command-line?
> > >     > >
> > >     > > Stefan
> > >     > 
> > >     > UUID will in fact come from the QEMU command line. VxHS is not doing
> > >     > anything special here. It will just use the value already available to
> > >     > qemu-kvm process.
> > >     > 
> > >     > QemuUUID qemu_uuid;
> > >     > bool qemu_uuid_set;
> > >     > 
> > >     > Both the above are defined in vl.c. vl.c will provide the strong
> > >     > symbol when available. There are certain binaries that do not get
> > >     > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > >     > affect for such binaries, and in this case, the default VXHS UUID will
> > >     > get picked up. I had, in a previous email, explained how we plan to
> > >     > use the default UUID. In the regular case, the VxHS controller will
> > >     > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > >     > may choose to grant temporary access to specific vdisks for these
> > >     > binaries depending on the workflow.
> > >     
> > >     That idea sounds like a security problem.  During this time window
> > >     anyone could use the default UUID to access the data?
> > >     
> > >     Just make the UUID (or TLS client certificate file) a command-line
> > >     parameter that qemu-system, qemu-img, and other tools accept (e.g.
> > >     qemu-img via the --image-opts/--object syntax).
> > >     
> > > [Ketan]
> > > Sounds fair. Would it be ok to take this up after the driver is
> > > merged for the upcoming QEMU release?
> > 
> > I don't think we can merge code with known security flaws, particularly
> > if fixing these flaws will involve adding and/or changing command line
> > parameters for the block driver.
> >
> 
> We do support some protocols, such as gluster, that do not have robust
> authentication frameworks over tcp/ip.  Of course, these protocols have been
> in as a driver for several years (and, gluster does support unix sockets).

NB, gluster *does* have secure access control. It uses the verified x509
certificate identity as a token against which access control rules are
placed on volumes.

It isn't authentication in the traditional sense most people think of it,
but it does provide a secure authorization facility.

> We seem to be establishing a rule for QEMU, that is "no new protocol drivers
> without secure authentication".  That is a good thing. The existence of
> current protocol drivers that don't meet that criteria is potentially
> confusing for new contributors, however.  (As a side note to myself -- this
> is probably a good thing to add to the wiki, if it is not there already).

It's been my goal to fix / enhance everything in QEMU that uses network and
does not have secure encryption + access control facilities. eg by adding
TLS support to the NBD driver, and providing the secure mechanism for feeding
passwords into QEMU for things like curl, iscsi, etc. We're getting pretty
close to having at least the option to use encryption + access control via
TLS certs or SASL on every key network based feature in QEMU.

> I think a non-secure scheme is worse than no scheme at all, because it
> becomes relied upon and promises something it cannot deliver.  In that vein,
> would you object to a vxhs protocol driver that did no authentication at all
> (similar to gluster), or do you think the above rule is a new hard rule for
> protocol drivers?

Adding support for a known insecure authentication scheme is a clear
no-go as that's pretty much immediate CVE terrority when we release it,
as you give people the illusion of security where none exists.

IMHO, any new network protocol that we add to QEMU should at least be
capable of having secure encryption & access control enabled, unless it
is a long term pre-existing standard - even those have pretty much all
been given strong security extensions over the years as it became clear
that internal networks are often just as hostile as public networks.
eg the work we did to add TLS to VNC in 2007, or more recently adding
TLS to NBD. SPICE by constrast as a modern protocol had TLS right from
the start.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 17:39             ` Daniel P. Berrange
@ 2017-02-21 18:06               ` Jeff Cody
  2017-02-21 18:56                 ` Daniel P. Berrange
  0 siblings, 1 reply; 56+ messages in thread
From: Jeff Cody @ 2017-02-21 18:06 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Ketan Nilangekar, Stefan Hajnoczi, ashish mittal, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 21, 2017 at 05:39:12PM +0000, Daniel P. Berrange wrote:
> On Tue, Feb 21, 2017 at 05:21:46PM +0000, Ketan Nilangekar wrote:
> > 
> > 
> > On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:
> > 
> >     On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> >     > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> >     > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> >     > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> >     > >>
> >     > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> >     > >>     > Hi,
> >     > >>     >
> >     > >>     > I am getting the following error with checkpatch.pl
> >     > >>     >
> >     > >>     > ERROR: externs should be avoided in .c files
> >     > >>     > #78: FILE: block/vxhs.c:28:
> >     > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> >     > >>     >
> >     > >>     > Is there any way to get around this, or does it mean that I would have
> >     > >>     > to add a vxhs.h just for this one entry?
> >     > >>     >
> >     > >>
> >     > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> >     > >>     cert.
> >     > >>
> >     > >> [ketan]
> >     > >> Is there another identity that can be used for uniquely identifying instances?
> >     > >> The requirement was to enforce vdisk access to owner instances.
> >     > >
> >     > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> >     > > strong qemu_uuid symbol?
> >     > >
> >     > > Why aren't configuration parameters like the UUID coming from the QEMU
> >     > > command-line?
> >     > >
> >     > > Stefan
> >     > 
> >     > UUID will in fact come from the QEMU command line. VxHS is not doing
> >     > anything special here. It will just use the value already available to
> >     > qemu-kvm process.
> >     > 
> >     > QemuUUID qemu_uuid;
> >     > bool qemu_uuid_set;
> >     > 
> >     > Both the above are defined in vl.c. vl.c will provide the strong
> >     > symbol when available. There are certain binaries that do not get
> >     > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> >     > affect for such binaries, and in this case, the default VXHS UUID will
> >     > get picked up. I had, in a previous email, explained how we plan to
> >     > use the default UUID. In the regular case, the VxHS controller will
> >     > not allow access to the default UUID (non qemu-kvm) binaries, but it
> >     > may choose to grant temporary access to specific vdisks for these
> >     > binaries depending on the workflow.
> >     
> >     That idea sounds like a security problem.  During this time window
> >     anyone could use the default UUID to access the data?
> >     
> >     Just make the UUID (or TLS client certificate file) a command-line
> >     parameter that qemu-system, qemu-img, and other tools accept (e.g.
> >     qemu-img via the --image-opts/--object syntax).
> >     
> > [Ketan]
> > Sounds fair. Would it be ok to take this up after the driver is
> > merged for the upcoming QEMU release?
> 
> I don't think we can merge code with known security flaws, particularly
> if fixing these flaws will involve adding and/or changing command line
> parameters for the block driver.
>

We do support some protocols, such as gluster, that do not have robust
authentication frameworks over tcp/ip.  Of course, these protocols have been
in as a driver for several years (and, gluster does support unix sockets).

We seem to be establishing a rule for QEMU, that is "no new protocol drivers
without secure authentication".  That is a good thing. The existence of
current protocol drivers that don't meet that criteria is potentially
confusing for new contributors, however.  (As a side note to myself -- this
is probably a good thing to add to the wiki, if it is not there already).

I think a non-secure scheme is worse than no scheme at all, because it
becomes relied upon and promises something it cannot deliver.  In that vein,
would you object to a vxhs protocol driver that did no authentication at all
(similar to gluster), or do you think the above rule is a new hard rule for
protocol drivers?


Jeff

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 17:21           ` Ketan Nilangekar
@ 2017-02-21 17:39             ` Daniel P. Berrange
  2017-02-21 18:06               ` Jeff Cody
  2017-02-22 14:25             ` Stefan Hajnoczi
  1 sibling, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-21 17:39 UTC (permalink / raw)
  To: Ketan Nilangekar
  Cc: Stefan Hajnoczi, ashish mittal, Jeff Cody, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 21, 2017 at 05:21:46PM +0000, Ketan Nilangekar wrote:
> 
> 
> On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:
> 
>     On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
>     > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
>     > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
>     > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
>     > >>
>     > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
>     > >>     > Hi,
>     > >>     >
>     > >>     > I am getting the following error with checkpatch.pl
>     > >>     >
>     > >>     > ERROR: externs should be avoided in .c files
>     > >>     > #78: FILE: block/vxhs.c:28:
>     > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
>     > >>     >
>     > >>     > Is there any way to get around this, or does it mean that I would have
>     > >>     > to add a vxhs.h just for this one entry?
>     > >>     >
>     > >>
>     > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
>     > >>     cert.
>     > >>
>     > >> [ketan]
>     > >> Is there another identity that can be used for uniquely identifying instances?
>     > >> The requirement was to enforce vdisk access to owner instances.
>     > >
>     > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
>     > > strong qemu_uuid symbol?
>     > >
>     > > Why aren't configuration parameters like the UUID coming from the QEMU
>     > > command-line?
>     > >
>     > > Stefan
>     > 
>     > UUID will in fact come from the QEMU command line. VxHS is not doing
>     > anything special here. It will just use the value already available to
>     > qemu-kvm process.
>     > 
>     > QemuUUID qemu_uuid;
>     > bool qemu_uuid_set;
>     > 
>     > Both the above are defined in vl.c. vl.c will provide the strong
>     > symbol when available. There are certain binaries that do not get
>     > linked with vl.c (e.g. qemu-img). The weak symbol will come into
>     > affect for such binaries, and in this case, the default VXHS UUID will
>     > get picked up. I had, in a previous email, explained how we plan to
>     > use the default UUID. In the regular case, the VxHS controller will
>     > not allow access to the default UUID (non qemu-kvm) binaries, but it
>     > may choose to grant temporary access to specific vdisks for these
>     > binaries depending on the workflow.
>     
>     That idea sounds like a security problem.  During this time window
>     anyone could use the default UUID to access the data?
>     
>     Just make the UUID (or TLS client certificate file) a command-line
>     parameter that qemu-system, qemu-img, and other tools accept (e.g.
>     qemu-img via the --image-opts/--object syntax).
>     
> [Ketan]
> Sounds fair. Would it be ok to take this up after the driver is
> merged for the upcoming QEMU release?

I don't think we can merge code with known security flaws, particularly
if fixing these flaws will involve adding and/or changing command line
parameters for the block driver.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 10:59         ` Stefan Hajnoczi
  2017-02-21 11:33           ` Daniel P. Berrange
@ 2017-02-21 17:21           ` Ketan Nilangekar
  2017-02-21 17:39             ` Daniel P. Berrange
  2017-02-22 14:25             ` Stefan Hajnoczi
  1 sibling, 2 replies; 56+ messages in thread
From: Ketan Nilangekar @ 2017-02-21 17:21 UTC (permalink / raw)
  To: Stefan Hajnoczi, ashish mittal
  Cc: Jeff Cody, qemu-devel, Paolo Bonzini, Kevin Wolf,
	Markus Armbruster, Daniel P. Berrange, Fam Zheng, Ashish Mittal,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan



On 2/21/17, 5:59 AM, "Stefan Hajnoczi" <stefanha@gmail.com> wrote:

    On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
    > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
    > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
    > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
    > >>
    > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
    > >>     > Hi,
    > >>     >
    > >>     > I am getting the following error with checkpatch.pl
    > >>     >
    > >>     > ERROR: externs should be avoided in .c files
    > >>     > #78: FILE: block/vxhs.c:28:
    > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
    > >>     >
    > >>     > Is there any way to get around this, or does it mean that I would have
    > >>     > to add a vxhs.h just for this one entry?
    > >>     >
    > >>
    > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
    > >>     cert.
    > >>
    > >> [ketan]
    > >> Is there another identity that can be used for uniquely identifying instances?
    > >> The requirement was to enforce vdisk access to owner instances.
    > >
    > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
    > > strong qemu_uuid symbol?
    > >
    > > Why aren't configuration parameters like the UUID coming from the QEMU
    > > command-line?
    > >
    > > Stefan
    > 
    > UUID will in fact come from the QEMU command line. VxHS is not doing
    > anything special here. It will just use the value already available to
    > qemu-kvm process.
    > 
    > QemuUUID qemu_uuid;
    > bool qemu_uuid_set;
    > 
    > Both the above are defined in vl.c. vl.c will provide the strong
    > symbol when available. There are certain binaries that do not get
    > linked with vl.c (e.g. qemu-img). The weak symbol will come into
    > affect for such binaries, and in this case, the default VXHS UUID will
    > get picked up. I had, in a previous email, explained how we plan to
    > use the default UUID. In the regular case, the VxHS controller will
    > not allow access to the default UUID (non qemu-kvm) binaries, but it
    > may choose to grant temporary access to specific vdisks for these
    > binaries depending on the workflow.
    
    That idea sounds like a security problem.  During this time window
    anyone could use the default UUID to access the data?
    
    Just make the UUID (or TLS client certificate file) a command-line
    parameter that qemu-system, qemu-img, and other tools accept (e.g.
    qemu-img via the --image-opts/--object syntax).
    
[Ketan]
Sounds fair. Would it be ok to take this up after the driver is merged for the upcoming QEMU release?

    Stefan
    


^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-21 10:59         ` Stefan Hajnoczi
@ 2017-02-21 11:33           ` Daniel P. Berrange
  2017-02-22 14:09             ` Stefan Hajnoczi
  2017-02-21 17:21           ` Ketan Nilangekar
  1 sibling, 1 reply; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-21 11:33 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: ashish mittal, Ketan Nilangekar, Jeff Cody, qemu-devel,
	Paolo Bonzini, Kevin Wolf, Markus Armbruster, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Tue, Feb 21, 2017 at 10:59:18AM +0000, Stefan Hajnoczi wrote:
> On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> > On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> > >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> > >>
> > >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > >>     > Hi,
> > >>     >
> > >>     > I am getting the following error with checkpatch.pl
> > >>     >
> > >>     > ERROR: externs should be avoided in .c files
> > >>     > #78: FILE: block/vxhs.c:28:
> > >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> > >>     >
> > >>     > Is there any way to get around this, or does it mean that I would have
> > >>     > to add a vxhs.h just for this one entry?
> > >>     >
> > >>
> > >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> > >>     cert.
> > >>
> > >> [ketan]
> > >> Is there another identity that can be used for uniquely identifying instances?
> > >> The requirement was to enforce vdisk access to owner instances.
> > >
> > > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > > strong qemu_uuid symbol?
> > >
> > > Why aren't configuration parameters like the UUID coming from the QEMU
> > > command-line?
> > >
> > > Stefan
> > 
> > UUID will in fact come from the QEMU command line. VxHS is not doing
> > anything special here. It will just use the value already available to
> > qemu-kvm process.
> > 
> > QemuUUID qemu_uuid;
> > bool qemu_uuid_set;
> > 
> > Both the above are defined in vl.c. vl.c will provide the strong
> > symbol when available. There are certain binaries that do not get
> > linked with vl.c (e.g. qemu-img). The weak symbol will come into
> > affect for such binaries, and in this case, the default VXHS UUID will
> > get picked up. I had, in a previous email, explained how we plan to
> > use the default UUID. In the regular case, the VxHS controller will
> > not allow access to the default UUID (non qemu-kvm) binaries, but it
> > may choose to grant temporary access to specific vdisks for these
> > binaries depending on the workflow.
> 
> That idea sounds like a security problem.  During this time window
> anyone could use the default UUID to access the data?

Any use of the VM UUID as a means to control authorization on the
server side is a security flaw, as this is a public value which
cannot be trusted on its own.

There needs to be some kind of authentication step to verify the
reported identity, eg a password associated with the VM UUID that
is validated before trusting the VM UUID.

Alternatively there needs to be a completely separate UUID, unrelated
to the VM UUID, which is treated as a private value (eg uses the
'-object secret' framework in QEMU)

> Just make the UUID (or TLS client certificate file) a command-line
> parameter that qemu-system, qemu-img, and other tools accept (e.g.
> qemu-img via the --image-opts/--object syntax).

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-20 11:34       ` ashish mittal
@ 2017-02-21 10:59         ` Stefan Hajnoczi
  2017-02-21 11:33           ` Daniel P. Berrange
  2017-02-21 17:21           ` Ketan Nilangekar
  0 siblings, 2 replies; 56+ messages in thread
From: Stefan Hajnoczi @ 2017-02-21 10:59 UTC (permalink / raw)
  To: ashish mittal
  Cc: Ketan Nilangekar, Jeff Cody, qemu-devel, Paolo Bonzini,
	Kevin Wolf, Markus Armbruster, Daniel P. Berrange, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

[-- Attachment #1: Type: text/plain, Size: 2434 bytes --]

On Mon, Feb 20, 2017 at 03:34:57AM -0800, ashish mittal wrote:
> On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> > On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> >> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> >>
> >>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> >>     > Hi,
> >>     >
> >>     > I am getting the following error with checkpatch.pl
> >>     >
> >>     > ERROR: externs should be avoided in .c files
> >>     > #78: FILE: block/vxhs.c:28:
> >>     > +QemuUUID qemu_uuid __attribute__ ((weak));
> >>     >
> >>     > Is there any way to get around this, or does it mean that I would have
> >>     > to add a vxhs.h just for this one entry?
> >>     >
> >>
> >>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> >>     cert.
> >>
> >> [ketan]
> >> Is there another identity that can be used for uniquely identifying instances?
> >> The requirement was to enforce vdisk access to owner instances.
> >
> > The qemu_uuid weak attribute looks suspect.  What is going to provide a
> > strong qemu_uuid symbol?
> >
> > Why aren't configuration parameters like the UUID coming from the QEMU
> > command-line?
> >
> > Stefan
> 
> UUID will in fact come from the QEMU command line. VxHS is not doing
> anything special here. It will just use the value already available to
> qemu-kvm process.
> 
> QemuUUID qemu_uuid;
> bool qemu_uuid_set;
> 
> Both the above are defined in vl.c. vl.c will provide the strong
> symbol when available. There are certain binaries that do not get
> linked with vl.c (e.g. qemu-img). The weak symbol will come into
> affect for such binaries, and in this case, the default VXHS UUID will
> get picked up. I had, in a previous email, explained how we plan to
> use the default UUID. In the regular case, the VxHS controller will
> not allow access to the default UUID (non qemu-kvm) binaries, but it
> may choose to grant temporary access to specific vdisks for these
> binaries depending on the workflow.

That idea sounds like a security problem.  During this time window
anyone could use the default UUID to access the data?

Just make the UUID (or TLS client certificate file) a command-line
parameter that qemu-system, qemu-img, and other tools accept (e.g.
qemu-img via the --image-opts/--object syntax).

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-20 11:02     ` Stefan Hajnoczi
@ 2017-02-20 11:34       ` ashish mittal
  2017-02-21 10:59         ` Stefan Hajnoczi
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-20 11:34 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Ketan Nilangekar, Jeff Cody, qemu-devel, Paolo Bonzini,
	Kevin Wolf, Markus Armbruster, Daniel P. Berrange, Fam Zheng,
	Ashish Mittal, John Ferlan, Buddhi Madhav, Suraj Singh,
	Nitin Jerath, Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Mon, Feb 20, 2017 at 3:02 AM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
>> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
>>
>>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
>>     > Hi,
>>     >
>>     > I am getting the following error with checkpatch.pl
>>     >
>>     > ERROR: externs should be avoided in .c files
>>     > #78: FILE: block/vxhs.c:28:
>>     > +QemuUUID qemu_uuid __attribute__ ((weak));
>>     >
>>     > Is there any way to get around this, or does it mean that I would have
>>     > to add a vxhs.h just for this one entry?
>>     >
>>
>>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
>>     cert.
>>
>> [ketan]
>> Is there another identity that can be used for uniquely identifying instances?
>> The requirement was to enforce vdisk access to owner instances.
>
> The qemu_uuid weak attribute looks suspect.  What is going to provide a
> strong qemu_uuid symbol?
>
> Why aren't configuration parameters like the UUID coming from the QEMU
> command-line?
>
> Stefan

UUID will in fact come from the QEMU command line. VxHS is not doing
anything special here. It will just use the value already available to
qemu-kvm process.

QemuUUID qemu_uuid;
bool qemu_uuid_set;

Both the above are defined in vl.c. vl.c will provide the strong
symbol when available. There are certain binaries that do not get
linked with vl.c (e.g. qemu-img). The weak symbol will come into
affect for such binaries, and in this case, the default VXHS UUID will
get picked up. I had, in a previous email, explained how we plan to
use the default UUID. In the regular case, the VxHS controller will
not allow access to the default UUID (non qemu-kvm) binaries, but it
may choose to grant temporary access to specific vdisks for these
binaries depending on the workflow.

Regards,
Ashish

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-18  0:30   ` Ketan Nilangekar
  2017-02-20  9:50     ` Daniel P. Berrange
@ 2017-02-20 11:02     ` Stefan Hajnoczi
  2017-02-20 11:34       ` ashish mittal
  1 sibling, 1 reply; 56+ messages in thread
From: Stefan Hajnoczi @ 2017-02-20 11:02 UTC (permalink / raw)
  To: Ketan Nilangekar
  Cc: Jeff Cody, ashish mittal, qemu-devel, Paolo Bonzini, Kevin Wolf,
	Markus Armbruster, Daniel P. Berrange, Fam Zheng, Ashish Mittal,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

[-- Attachment #1: Type: text/plain, Size: 1056 bytes --]

On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> 
>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
>     > Hi,
>     > 
>     > I am getting the following error with checkpatch.pl
>     > 
>     > ERROR: externs should be avoided in .c files
>     > #78: FILE: block/vxhs.c:28:
>     > +QemuUUID qemu_uuid __attribute__ ((weak));
>     > 
>     > Is there any way to get around this, or does it mean that I would have
>     > to add a vxhs.h just for this one entry?
>     >
>     
>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
>     cert.
> 
> [ketan]
> Is there another identity that can be used for uniquely identifying instances?
> The requirement was to enforce vdisk access to owner instances.

The qemu_uuid weak attribute looks suspect.  What is going to provide a
strong qemu_uuid symbol?

Why aren't configuration parameters like the UUID coming from the QEMU
command-line?

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-18  0:30   ` Ketan Nilangekar
@ 2017-02-20  9:50     ` Daniel P. Berrange
  2017-02-20 11:02     ` Stefan Hajnoczi
  1 sibling, 0 replies; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-20  9:50 UTC (permalink / raw)
  To: Ketan Nilangekar
  Cc: Jeff Cody, ashish mittal, qemu-devel, Paolo Bonzini, Kevin Wolf,
	Markus Armbruster, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Sat, Feb 18, 2017 at 12:30:31AM +0000, Ketan Nilangekar wrote:
> On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:
> 
>     On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
>     > Hi,
>     > 
>     > I am getting the following error with checkpatch.pl
>     > 
>     > ERROR: externs should be avoided in .c files
>     > #78: FILE: block/vxhs.c:28:
>     > +QemuUUID qemu_uuid __attribute__ ((weak));
>     > 
>     > Is there any way to get around this, or does it mean that I would have
>     > to add a vxhs.h just for this one entry?
>     >
>     
>     I remain skeptical on the use of the qemu_uuid as a way to select the TLS
>     cert.
> 
> [ketan]
> Is there another identity that can be used for uniquely identifying instances?
> The requirement was to enforce vdisk access to owner instances.

The UUID is a bad way to do any kind of access control as QEMU could simply
lie about its UUID.

If the server needs to identify the client to do access control you need
something non-spoofable. In the absence of having an authentication protocol
built into the libqnio protocol, the best you could do would be to use the
TLS client certificate distinguished name. QEMU can't lie about that without
having access to the other certificate file - which would be blocked by
SELinux

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-17 21:42 ` Jeff Cody
  2017-02-18  0:30   ` Ketan Nilangekar
@ 2017-02-20  9:44   ` Daniel P. Berrange
  1 sibling, 0 replies; 56+ messages in thread
From: Daniel P. Berrange @ 2017-02-20  9:44 UTC (permalink / raw)
  To: Jeff Cody
  Cc: ashish mittal, qemu-devel, Paolo Bonzini, Kevin Wolf,
	Markus Armbruster, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Fri, Feb 17, 2017 at 04:42:15PM -0500, Jeff Cody wrote:
> On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> > Hi,
> > 
> > I am getting the following error with checkpatch.pl
> > 
> > ERROR: externs should be avoided in .c files
> > #78: FILE: block/vxhs.c:28:
> > +QemuUUID qemu_uuid __attribute__ ((weak));
> > 
> > Is there any way to get around this, or does it mean that I would have
> > to add a vxhs.h just for this one entry?
> >
> 
> I remain skeptical on the use of the qemu_uuid as a way to select the TLS
> cert.

Yes, we should not be hardcoding arbitrary path lookup policies like that
in QEMU. The libqnio API should allow QEMU to specify what paths it wants
to use for certs directly. That allows the admin the flexibility to decide
their own policy for where to put certs and the policy on which certs are
used for which purpose.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-17 21:42 ` Jeff Cody
@ 2017-02-18  0:30   ` Ketan Nilangekar
  2017-02-20  9:50     ` Daniel P. Berrange
  2017-02-20 11:02     ` Stefan Hajnoczi
  2017-02-20  9:44   ` Daniel P. Berrange
  1 sibling, 2 replies; 56+ messages in thread
From: Ketan Nilangekar @ 2017-02-18  0:30 UTC (permalink / raw)
  To: Jeff Cody, ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On 2/17/17, 1:42 PM, "Jeff Cody" <jcody@redhat.com> wrote:

    On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
    > Hi,
    > 
    > I am getting the following error with checkpatch.pl
    > 
    > ERROR: externs should be avoided in .c files
    > #78: FILE: block/vxhs.c:28:
    > +QemuUUID qemu_uuid __attribute__ ((weak));
    > 
    > Is there any way to get around this, or does it mean that I would have
    > to add a vxhs.h just for this one entry?
    >
    
    I remain skeptical on the use of the qemu_uuid as a way to select the TLS
    cert.

[ketan]
Is there another identity that can be used for uniquely identifying instances?
The requirement was to enforce vdisk access to owner instances.

    
    But that aside, and looking at it strictly from a checkpatch.pl point of
    view, I think one could make a case that if there is no header file, the
    error could be ignored.
    


^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
  2017-02-16 22:24 ashish mittal
@ 2017-02-17 21:42 ` Jeff Cody
  2017-02-18  0:30   ` Ketan Nilangekar
  2017-02-20  9:44   ` Daniel P. Berrange
  0 siblings, 2 replies; 56+ messages in thread
From: Jeff Cody @ 2017-02-17 21:42 UTC (permalink / raw)
  To: ashish mittal
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

On Thu, Feb 16, 2017 at 02:24:19PM -0800, ashish mittal wrote:
> Hi,
> 
> I am getting the following error with checkpatch.pl
> 
> ERROR: externs should be avoided in .c files
> #78: FILE: block/vxhs.c:28:
> +QemuUUID qemu_uuid __attribute__ ((weak));
> 
> Is there any way to get around this, or does it mean that I would have
> to add a vxhs.h just for this one entry?
>

I remain skeptical on the use of the qemu_uuid as a way to select the TLS
cert.

But that aside, and looking at it strictly from a checkpatch.pl point of
view, I think one could make a case that if there is no header file, the
error could be ignored.

^ permalink raw reply	[flat|nested] 56+ messages in thread

* Re: [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"
@ 2017-02-16 22:24 ashish mittal
  2017-02-17 21:42 ` Jeff Cody
  0 siblings, 1 reply; 56+ messages in thread
From: ashish mittal @ 2017-02-16 22:24 UTC (permalink / raw)
  To: Jeff Cody
  Cc: qemu-devel, Paolo Bonzini, Kevin Wolf, Markus Armbruster,
	Daniel P. Berrange, Fam Zheng, Ashish Mittal, Stefan Hajnoczi,
	John Ferlan, Buddhi Madhav, Suraj Singh, Nitin Jerath,
	Peter Maydell, Ketan Nilangekar, Abhijit Dey, Venkatesha M.G.,
	Rakesh Ranjan

Hi,

I am getting the following error with checkpatch.pl

ERROR: externs should be avoided in .c files
#78: FILE: block/vxhs.c:28:
+QemuUUID qemu_uuid __attribute__ ((weak));

Is there any way to get around this, or does it mean that I would have
to add a vxhs.h just for this one entry?

Thanks,
Ashish

^ permalink raw reply	[flat|nested] 56+ messages in thread

end of thread, other threads:[~2017-03-27  3:07 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-09  5:23 [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Ashish Mittal
2017-02-09  5:23 ` [Qemu-devel] [PATCH v8 2/2] block/vxhs.c: Add qemu-iotests for new block device type "vxhs" Ashish Mittal
2017-02-09  6:29 ` [Qemu-devel] [PATCH v8 1/2] block/vxhs.c: Add support for a new block device type called "vxhs" Jeff Cody
2017-02-09  9:24   ` ashish mittal
2017-02-09 14:32     ` Jeff Cody
2017-02-09 16:14       ` ashish mittal
2017-02-09 16:50         ` Jeff Cody
2017-02-09 18:08           ` ashish mittal
2017-02-09 18:45             ` ashish mittal
2017-02-10  0:27               ` ashish mittal
2017-02-10  2:18                 ` Jeff Cody
2017-02-14 20:51     ` Jeff Cody
2017-02-14 22:34       ` ashish mittal
2017-02-15  3:02         ` ashish mittal
2017-02-15  3:54           ` Jeff Cody
2017-02-15 20:34             ` ashish mittal
2017-02-16 22:24 ashish mittal
2017-02-17 21:42 ` Jeff Cody
2017-02-18  0:30   ` Ketan Nilangekar
2017-02-20  9:50     ` Daniel P. Berrange
2017-02-20 11:02     ` Stefan Hajnoczi
2017-02-20 11:34       ` ashish mittal
2017-02-21 10:59         ` Stefan Hajnoczi
2017-02-21 11:33           ` Daniel P. Berrange
2017-02-22 14:09             ` Stefan Hajnoczi
2017-02-22 14:22               ` Daniel P. Berrange
2017-02-22 14:44                 ` Jeff Cody
2017-02-24  4:19                   ` ashish mittal
2017-02-24  9:19                     ` Daniel P. Berrange
2017-02-24 23:30                       ` ashish mittal
2017-02-27  9:22                         ` Daniel P. Berrange
2017-02-28 22:51                           ` ashish mittal
2017-03-01  9:18                             ` Daniel P. Berrange
2017-03-06  0:26                               ` ashish mittal
2017-03-06  9:23                                 ` Daniel P. Berrange
2017-03-08  1:27                                   ` ashish mittal
2017-03-08  9:13                                     ` Daniel P. Berrange
2017-03-08 13:04                                       ` Ketan Nilangekar
2017-03-08 17:59                                         ` ashish mittal
2017-03-08 18:11                                           ` Daniel P. Berrange
2017-03-11  3:04                                             ` ashish mittal
2017-03-13  9:56                                               ` Daniel P. Berrange
2017-03-13  9:57                                     ` Daniel P. Berrange
2017-03-17  0:29                                       ` ashish mittal
2017-03-18  1:44                                         ` ashish mittal
2017-03-20 12:55                                           ` Daniel P. Berrange
2017-03-23  0:03                                             ` ashish mittal
2017-03-27  3:07                                               ` ashish mittal
2017-02-21 17:21           ` Ketan Nilangekar
2017-02-21 17:39             ` Daniel P. Berrange
2017-02-21 18:06               ` Jeff Cody
2017-02-21 18:56                 ` Daniel P. Berrange
2017-02-21 19:25                   ` Jeff Cody
2017-02-22 10:12                     ` Daniel P. Berrange
2017-02-22 14:25             ` Stefan Hajnoczi
2017-02-20  9:44   ` Daniel P. Berrange

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.