From: Fam Zheng <famz@redhat.com>
To: Jeff Cody <jcody@redhat.com>
Cc: qemu-devel@nongnu.org, kwolf@redhat.com, pbonzini@redhat.com,
qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 1/7] iscsi: Split URL into individual options
Date: Tue, 7 Feb 2017 18:06:44 +0800 [thread overview]
Message-ID: <20170207100644.GC19280@lemon.lan> (raw)
In-Reply-To: <369a6fb1364a60de3af3e3454906564a4033ab59.1485365834.git.jcody@redhat.com>
On Wed, 01/25 12:42, Jeff Cody wrote:
> From: Kevin Wolf <kwolf@redhat.com>
>
> This introduces a .bdrv_parse_filename handler for iscsi which parses an
> URL if given and translates it to individual options.
>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
> block/iscsi.c | 189 ++++++++++++++++++++++++++++++++++++++++++----------------
> 1 file changed, 136 insertions(+), 53 deletions(-)
>
> diff --git a/block/iscsi.c b/block/iscsi.c
> index 6aeeb9e..97cff30 100644
> --- a/block/iscsi.c
> +++ b/block/iscsi.c
> @@ -1470,20 +1470,6 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
> }
> }
>
> -/* TODO Convert to fine grained options */
> -static QemuOptsList runtime_opts = {
> - .name = "iscsi",
> - .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
> - .desc = {
> - {
> - .name = "filename",
> - .type = QEMU_OPT_STRING,
> - .help = "URL to the iscsi image",
> - },
> - { /* end of list */ }
> - },
> -};
> -
> static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
> int evpd, int pc, void **inq, Error **errp)
> {
> @@ -1605,20 +1591,98 @@ out:
> * We support iscsi url's on the form
> * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
> */
> +static void iscsi_parse_filename(const char *filename, QDict *options,
> + Error **errp)
> +{
> + struct iscsi_url *iscsi_url;
> + const char *transport_name;
> + char *lun_str;
> +
> + iscsi_url = iscsi_parse_full_url(NULL, filename);
> + if (iscsi_url == NULL) {
> + error_setg(errp, "Failed to parse URL : %s", filename);
> + return;
> + }
> +
> +#if LIBISCSI_API_VERSION >= (20160603)
> + switch (iscsi_url->transport) {
> + case TCP_TRANSPORT: transport_name = "tcp"; break;
> + case ISER_TRANSPORT: transport_name = "iser"; break;
> + default:
> + error_setg(errp, "Unknown transport type (%d)",
> + iscsi_url->transport);
> + return;
checkpatch.pl doesn't like how this switch block is formatted. If you fix it:
Reviewed-by: Fam Zheng <famz@redhat.com>
> + }
> +#else
> + transport_name = "tcp";
> +#endif
> +
> + qdict_set_default_str(options, "transport", transport_name);
> + qdict_set_default_str(options, "portal", iscsi_url->portal);
> + qdict_set_default_str(options, "target", iscsi_url->target);
> +
> + lun_str = g_strdup_printf("%d", iscsi_url->lun);
> + qdict_set_default_str(options, "lun", lun_str);
> + g_free(lun_str);
> +
> + if (iscsi_url->user[0] != '\0') {
> + qdict_set_default_str(options, "user", iscsi_url->user);
> + qdict_set_default_str(options, "password", iscsi_url->passwd);
> + }
> +
> + iscsi_destroy_url(iscsi_url);
> +}
> +
> +/* TODO Add -iscsi options */
> +static QemuOptsList runtime_opts = {
> + .name = "iscsi",
> + .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
> + .desc = {
> + {
> + .name = "transport",
> + .type = QEMU_OPT_STRING,
> + },
> + {
> + .name = "portal",
> + .type = QEMU_OPT_STRING,
> + },
> + {
> + .name = "target",
> + .type = QEMU_OPT_STRING,
> + },
> + {
> + .name = "user",
> + .type = QEMU_OPT_STRING,
> + },
> + {
> + .name = "password",
> + .type = QEMU_OPT_STRING,
> + },
> + {
> + .name = "lun",
> + .type = QEMU_OPT_NUMBER,
> + },
> + { /* end of list */ }
> + },
> +};
> +
> static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> Error **errp)
> {
> IscsiLun *iscsilun = bs->opaque;
> struct iscsi_context *iscsi = NULL;
> - struct iscsi_url *iscsi_url = NULL;
> struct scsi_task *task = NULL;
> struct scsi_inquiry_standard *inq = NULL;
> struct scsi_inquiry_supported_pages *inq_vpd;
> char *initiator_name = NULL;
> QemuOpts *opts;
> Error *local_err = NULL;
> - const char *filename;
> - int i, ret = 0, timeout = 0;
> + const char *transport_name, *portal, *target;
> + const char *user, *password;
> +#if LIBISCSI_API_VERSION >= (20160603)
> + enum iscsi_transport_type transport;
> +#endif
> + int i, ret = 0, timeout = 0, lun;
>
> opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
> qemu_opts_absorb_qdict(opts, options, &local_err);
> @@ -1628,18 +1692,41 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> goto out;
> }
>
> - filename = qemu_opt_get(opts, "filename");
> + transport_name = qemu_opt_get(opts, "transport");
> + portal = qemu_opt_get(opts, "portal");
> + target = qemu_opt_get(opts, "target");
> + user = qemu_opt_get(opts, "user");
> + password = qemu_opt_get(opts, "password");
> + lun = qemu_opt_get_number(opts, "lun", 0);
>
> - iscsi_url = iscsi_parse_full_url(iscsi, filename);
> - if (iscsi_url == NULL) {
> - error_setg(errp, "Failed to parse URL : %s", filename);
> + if (!transport_name || !portal || !target) {
> + error_setg(errp, "Need all of transport, portal and target options");
> + ret = -EINVAL;
> + goto out;
> + }
> + if (user && !password) {
> + error_setg(errp, "If a user name is given, a password is required");
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + if (!strcmp(transport_name, "tcp")) {
> +#if LIBISCSI_API_VERSION >= (20160603)
> + transport = TCP_TRANSPORT;
> + } else if (!strcmp(transport_name, "iser")) {
> + transport = ISER_TRANSPORT;
> +#else
> + /* TCP is what older libiscsi versions always use */
> +#endif
> + } else {
> + error_setg(errp, "Unknown transport: %s", transport_name);
> ret = -EINVAL;
> goto out;
> }
>
> memset(iscsilun, 0, sizeof(IscsiLun));
>
> - initiator_name = parse_initiator_name(iscsi_url->target);
> + initiator_name = parse_initiator_name(target);
>
> iscsi = iscsi_create_context(initiator_name);
> if (iscsi == NULL) {
> @@ -1648,21 +1735,20 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> goto out;
> }
> #if LIBISCSI_API_VERSION >= (20160603)
> - if (iscsi_init_transport(iscsi, iscsi_url->transport)) {
> + if (iscsi_init_transport(iscsi, transport)) {
> error_setg(errp, ("Error initializing transport."));
> ret = -EINVAL;
> goto out;
> }
> #endif
> - if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
> + if (iscsi_set_targetname(iscsi, target)) {
> error_setg(errp, "iSCSI: Failed to set target name.");
> ret = -EINVAL;
> goto out;
> }
>
> - if (iscsi_url->user[0] != '\0') {
> - ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
> - iscsi_url->passwd);
> + if (user) {
> + ret = iscsi_set_initiator_username_pwd(iscsi, user, password);
> if (ret != 0) {
> error_setg(errp, "Failed to set initiator username and password");
> ret = -EINVAL;
> @@ -1671,7 +1757,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* check if we got CHAP username/password via the options */
> - parse_chap(iscsi, iscsi_url->target, &local_err);
> + parse_chap(iscsi, target, &local_err);
> if (local_err != NULL) {
> error_propagate(errp, local_err);
> ret = -EINVAL;
> @@ -1687,7 +1773,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
>
> /* check if we got HEADER_DIGEST via the options */
> - parse_header_digest(iscsi, iscsi_url->target, &local_err);
> + parse_header_digest(iscsi, target, &local_err);
> if (local_err != NULL) {
> error_propagate(errp, local_err);
> ret = -EINVAL;
> @@ -1695,7 +1781,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* timeout handling is broken in libiscsi before 1.15.0 */
> - timeout = parse_timeout(iscsi_url->target);
> + timeout = parse_timeout(target);
> #if LIBISCSI_API_VERSION >= 20150621
> iscsi_set_timeout(iscsi, timeout);
> #else
> @@ -1704,7 +1790,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> }
> #endif
>
> - if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
> + if (iscsi_full_connect_sync(iscsi, portal, lun) != 0) {
> error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
> iscsi_get_error(iscsi));
> ret = -EINVAL;
> @@ -1713,7 +1799,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
>
> iscsilun->iscsi = iscsi;
> iscsilun->aio_context = bdrv_get_aio_context(bs);
> - iscsilun->lun = iscsi_url->lun;
> + iscsilun->lun = lun;
> iscsilun->has_write_same = true;
>
> task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
> @@ -1816,9 +1902,6 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
> out:
> qemu_opts_del(opts);
> g_free(initiator_name);
> - if (iscsi_url != NULL) {
> - iscsi_destroy_url(iscsi_url);
> - }
> if (task != NULL) {
> scsi_free_scsi_task(task);
> }
> @@ -2027,15 +2110,15 @@ static BlockDriver bdrv_iscsi = {
> .format_name = "iscsi",
> .protocol_name = "iscsi",
>
> - .instance_size = sizeof(IscsiLun),
> - .bdrv_needs_filename = true,
> - .bdrv_file_open = iscsi_open,
> - .bdrv_close = iscsi_close,
> - .bdrv_create = iscsi_create,
> - .create_opts = &iscsi_create_opts,
> - .bdrv_reopen_prepare = iscsi_reopen_prepare,
> - .bdrv_reopen_commit = iscsi_reopen_commit,
> - .bdrv_invalidate_cache = iscsi_invalidate_cache,
> + .instance_size = sizeof(IscsiLun),
> + .bdrv_parse_filename = iscsi_parse_filename,
> + .bdrv_file_open = iscsi_open,
> + .bdrv_close = iscsi_close,
> + .bdrv_create = iscsi_create,
> + .create_opts = &iscsi_create_opts,
> + .bdrv_reopen_prepare = iscsi_reopen_prepare,
> + .bdrv_reopen_commit = iscsi_reopen_commit,
> + .bdrv_invalidate_cache = iscsi_invalidate_cache,
>
> .bdrv_getlength = iscsi_getlength,
> .bdrv_get_info = iscsi_get_info,
> @@ -2062,15 +2145,15 @@ static BlockDriver bdrv_iser = {
> .format_name = "iser",
> .protocol_name = "iser",
>
> - .instance_size = sizeof(IscsiLun),
> - .bdrv_needs_filename = true,
> - .bdrv_file_open = iscsi_open,
> - .bdrv_close = iscsi_close,
> - .bdrv_create = iscsi_create,
> - .create_opts = &iscsi_create_opts,
> - .bdrv_reopen_prepare = iscsi_reopen_prepare,
> - .bdrv_reopen_commit = iscsi_reopen_commit,
> - .bdrv_invalidate_cache = iscsi_invalidate_cache,
> + .instance_size = sizeof(IscsiLun),
> + .bdrv_parse_filename = iscsi_parse_filename,
> + .bdrv_file_open = iscsi_open,
> + .bdrv_close = iscsi_close,
> + .bdrv_create = iscsi_create,
> + .create_opts = &iscsi_create_opts,
> + .bdrv_reopen_prepare = iscsi_reopen_prepare,
> + .bdrv_reopen_commit = iscsi_reopen_commit,
> + .bdrv_invalidate_cache = iscsi_invalidate_cache,
>
> .bdrv_getlength = iscsi_getlength,
> .bdrv_get_info = iscsi_get_info,
> --
> 2.9.3
>
>
next prev parent reply other threads:[~2017-02-07 10:07 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-25 17:42 [Qemu-devel] [PATCH v2 0/7] iscsi: Add blockdev-add support Jeff Cody
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 1/7] iscsi: Split URL into individual options Jeff Cody
2017-02-07 10:06 ` Fam Zheng [this message]
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 2/7] iscsi: Handle -iscsi user/password in bdrv_parse_filename() Jeff Cody
2017-02-07 10:13 ` Fam Zheng
2017-02-17 13:26 ` Kevin Wolf
2017-02-17 14:09 ` Fam Zheng
2017-02-17 14:10 ` Fam Zheng
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 3/7] iscsi: Add initiator-name option Jeff Cody
2017-02-07 10:16 ` Fam Zheng
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 4/7] iscsi: Add header-digest option Jeff Cody
2017-02-07 10:18 ` Fam Zheng
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 5/7] iscsi: Add timeout option Jeff Cody
2017-02-07 10:21 ` Fam Zheng
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 6/7] iscsi: Add blockdev-add support Jeff Cody
2017-02-07 10:23 ` Fam Zheng
2017-02-17 21:40 ` Eric Blake
2017-02-17 21:47 ` Jeff Cody
2017-01-25 17:42 ` [Qemu-devel] [PATCH v2 7/7] QAPI: Fix blockdev-add example documentation Jeff Cody
2017-02-07 10:29 ` Fam Zheng
2017-01-25 17:57 ` [Qemu-devel] [PATCH v2 0/7] iscsi: Add blockdev-add support no-reply
2017-02-17 21:12 ` Jeff Cody
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170207100644.GC19280@lemon.lan \
--to=famz@redhat.com \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).