qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename()
@ 2019-02-25 19:08 Max Reitz
  2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 1/2] " Max Reitz
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Max Reitz @ 2019-02-25 19:08 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Richard W . M . Jones, Kevin Wolf

This series implements .bdrv_refresh_filename() for the ssh block
driver, along with an appropriate .bdrv_dirname() so we don't chop off
query strings for backing files with relative filenames.


v3:
- Keep iotests 104 and 207 working


Max Reitz (2):
  block/ssh: Implement .bdrv_refresh_filename()
  block/ssh: Implement .bdrv_dirname()

 block/ssh.c                   | 73 ++++++++++++++++++++++++++++++++---
 tests/qemu-iotests/207        | 10 ++---
 tests/qemu-iotests/207.out    | 10 ++---
 tests/qemu-iotests/common.rc  |  2 +-
 tests/qemu-iotests/iotests.py |  2 +-
 5 files changed, 80 insertions(+), 17 deletions(-)

-- 
2.20.1

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

* [Qemu-devel] [PATCH v3 1/2] block/ssh: Implement .bdrv_refresh_filename()
  2019-02-25 19:08 [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
@ 2019-02-25 19:08 ` Max Reitz
  2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 2/2] block/ssh: Implement .bdrv_dirname() Max Reitz
  2019-04-13 16:26 ` [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
  2 siblings, 0 replies; 5+ messages in thread
From: Max Reitz @ 2019-02-25 19:08 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Richard W . M . Jones, Kevin Wolf

This requires some changes to keep iotests 104 and 207 working.

qemu-img info in 104 will now return a filename including the user name
and the port, which need to be filtered by adjusting REMOTE_TEST_DIR in
common.rc.  This additional information has to be marked optional,
however (which is simple as REMOTE_TEST_DIR is a regex), because
otherwise 197 and 215 would fail: They use it (indirectly) to filter
qemu-img create output which contains a backing filename they have
passed to it -- which probably does not contain a user name or port
number.

The problem in 207 is a nice one to have: qemu-img info used to return
json:{} filenames, but with this patch it returns nice plain ones.  We
now need to adjust the filtering to hide the user name (and port number
while we are at it).  The simplest way to do this is to include both in
iotests.remote_filename() so that bdrv_refresh_filename() will not
change it, and then iotests.img_info_log() will filter it correctly
automatically.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
---
 block/ssh.c                   | 52 +++++++++++++++++++++++++++++++----
 tests/qemu-iotests/207        | 10 +++----
 tests/qemu-iotests/207.out    | 10 +++----
 tests/qemu-iotests/common.rc  |  2 +-
 tests/qemu-iotests/iotests.py |  2 +-
 5 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/block/ssh.c b/block/ssh.c
index 190ef95300..88401bbd31 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -75,6 +75,14 @@ typedef struct BDRVSSHState {
 
     /* Used to warn if 'flush' is not supported. */
     bool unsafe_flush_warning;
+
+    /*
+     * Store the user name for ssh_refresh_filename() because the
+     * default depends on the system you are on -- therefore, when we
+     * generate a filename, it should always contain the user name we
+     * are actually using.
+     */
+    char *user;
 } BDRVSSHState;
 
 static void ssh_state_init(BDRVSSHState *s)
@@ -87,6 +95,8 @@ static void ssh_state_init(BDRVSSHState *s)
 
 static void ssh_state_free(BDRVSSHState *s)
 {
+    g_free(s->user);
+
     if (s->sftp_handle) {
         libssh2_sftp_close(s->sftp_handle);
     }
@@ -640,14 +650,13 @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
                           int ssh_flags, int creat_mode, Error **errp)
 {
     int r, ret;
-    const char *user;
     long port = 0;
 
     if (opts->has_user) {
-        user = opts->user;
+        s->user = g_strdup(opts->user);
     } else {
-        user = g_get_user_name();
-        if (!user) {
+        s->user = g_strdup(g_get_user_name());
+        if (!s->user) {
             error_setg_errno(errp, errno, "Can't get user name");
             ret = -errno;
             goto err;
@@ -697,7 +706,7 @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
     }
 
     /* Authenticate. */
-    ret = authenticate(s, user, errp);
+    ret = authenticate(s, s->user, errp);
     if (ret < 0) {
         goto err;
     }
@@ -1254,6 +1263,38 @@ static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
     return ssh_grow_file(s, offset, errp);
 }
 
+static void ssh_refresh_filename(BlockDriverState *bs)
+{
+    BDRVSSHState *s = bs->opaque;
+    const char *path, *host_key_check;
+    int ret;
+
+    /*
+     * None of these options can be represented in a plain "host:port"
+     * format, so if any was given, we have to abort.
+     */
+    if (s->inet->has_ipv4 || s->inet->has_ipv6 || s->inet->has_to ||
+        s->inet->has_numeric)
+    {
+        return;
+    }
+
+    path = qdict_get_try_str(bs->full_open_options, "path");
+    assert(path); /* mandatory option */
+
+    host_key_check = qdict_get_try_str(bs->full_open_options, "host_key_check");
+
+    ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+                   "ssh://%s@%s:%s%s%s%s",
+                   s->user, s->inet->host, s->inet->port, path,
+                   host_key_check ? "?host_key_check=" : "",
+                   host_key_check ?: "");
+    if (ret >= sizeof(bs->exact_filename)) {
+        /* An overflow makes the filename unusable, so do not report any */
+        bs->exact_filename[0] = '\0';
+    }
+}
+
 static const char *const ssh_strong_runtime_opts[] = {
     "host",
     "port",
@@ -1280,6 +1321,7 @@ static BlockDriver bdrv_ssh = {
     .bdrv_getlength               = ssh_getlength,
     .bdrv_co_truncate             = ssh_co_truncate,
     .bdrv_co_flush_to_disk        = ssh_co_flush,
+    .bdrv_refresh_filename        = ssh_refresh_filename,
     .create_opts                  = &ssh_create_opts,
     .strong_runtime_opts          = ssh_strong_runtime_opts,
 };
diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
index dfd3c51bd1..b3816136f7 100755
--- a/tests/qemu-iotests/207
+++ b/tests/qemu-iotests/207
@@ -66,7 +66,7 @@ with iotests.FilePath('t.img') as disk_path, \
                           'size': 4194304 })
     vm.shutdown()
 
-    iotests.img_info_log(remote_path, filter_path=disk_path)
+    iotests.img_info_log(remote_path)
     iotests.log("")
     iotests.img_info_log(disk_path)
 
@@ -91,7 +91,7 @@ with iotests.FilePath('t.img') as disk_path, \
                           'size': 8388608 })
     vm.shutdown()
 
-    iotests.img_info_log(remote_path, filter_path=disk_path)
+    iotests.img_info_log(remote_path)
 
     vm.launch()
     blockdev_create(vm, { 'driver': 'ssh',
@@ -108,7 +108,7 @@ with iotests.FilePath('t.img') as disk_path, \
                           'size': 4194304 })
     vm.shutdown()
 
-    iotests.img_info_log(remote_path, filter_path=disk_path)
+    iotests.img_info_log(remote_path)
 
     md5_key = subprocess.check_output(
         'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
@@ -146,7 +146,7 @@ with iotests.FilePath('t.img') as disk_path, \
                           'size': 8388608 })
     vm.shutdown()
 
-    iotests.img_info_log(remote_path, filter_path=disk_path)
+    iotests.img_info_log(remote_path)
 
     sha1_key = subprocess.check_output(
         'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
@@ -184,7 +184,7 @@ with iotests.FilePath('t.img') as disk_path, \
                           'size': 4194304 })
     vm.shutdown()
 
-    iotests.img_info_log(remote_path, filter_path=disk_path)
+    iotests.img_info_log(remote_path)
 
     #
     # Invalid path and user
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
index 568e8619d0..8b8c28c7e1 100644
--- a/tests/qemu-iotests/207.out
+++ b/tests/qemu-iotests/207.out
@@ -5,7 +5,7 @@
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
+image: TEST_IMG
 file format: IMGFMT
 virtual size: 4.0M (4194304 bytes)
 
@@ -21,7 +21,7 @@ virtual size: 4.0M (4194304 bytes)
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
+image: TEST_IMG
 file format: IMGFMT
 virtual size: 8.0M (8388608 bytes)
 
@@ -30,7 +30,7 @@ virtual size: 8.0M (8388608 bytes)
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
+image: TEST_IMG
 file format: IMGFMT
 virtual size: 4.0M (4194304 bytes)
 
@@ -45,7 +45,7 @@ Job failed: remote host key does not match host_key_check 'wrong'
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
+image: TEST_IMG
 file format: IMGFMT
 virtual size: 8.0M (8388608 bytes)
 
@@ -60,7 +60,7 @@ Job failed: remote host key does not match host_key_check 'wrong'
 {"execute": "job-dismiss", "arguments": {"id": "job0"}}
 {"return": {}}
 
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
+image: TEST_IMG
 file format: IMGFMT
 virtual size: 4.0M (4194304 bytes)
 
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 09a27f02d0..f323fa2925 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -145,7 +145,7 @@ else
         TEST_IMG="nbd:127.0.0.1:10810"
     elif [ "$IMGPROTO" = "ssh" ]; then
         TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
-        REMOTE_TEST_DIR="ssh://127.0.0.1$TEST_DIR"
+        REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR"
         TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
     elif [ "$IMGPROTO" = "nfs" ]; then
         TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 4910fb2005..aa16d6cbdd 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -411,7 +411,7 @@ def remote_filename(path):
     if imgproto == 'file':
         return path
     elif imgproto == 'ssh':
-        return "ssh://127.0.0.1%s" % (path)
+        return "ssh://%s@127.0.0.1:22%s" % (os.environ.get('USER'), path)
     else:
         raise Exception("Protocol %s not supported" % (imgproto))
 
-- 
2.20.1

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

* [Qemu-devel] [PATCH v3 2/2] block/ssh: Implement .bdrv_dirname()
  2019-02-25 19:08 [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
  2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 1/2] " Max Reitz
@ 2019-02-25 19:08 ` Max Reitz
  2019-04-13 16:26 ` [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
  2 siblings, 0 replies; 5+ messages in thread
From: Max Reitz @ 2019-02-25 19:08 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Max Reitz, Richard W . M . Jones, Kevin Wolf

ssh_bdrv_dirname() is basically the generic bdrv_dirname(), except it
takes care not to silently chop off any query string (i.e.,
host_key_check).

Signed-off-by: Max Reitz <mreitz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
---
 block/ssh.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/block/ssh.c b/block/ssh.c
index 88401bbd31..b519c00869 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -1295,6 +1295,26 @@ static void ssh_refresh_filename(BlockDriverState *bs)
     }
 }
 
+static char *ssh_bdrv_dirname(BlockDriverState *bs, Error **errp)
+{
+    if (qdict_haskey(bs->full_open_options, "host_key_check")) {
+        /*
+         * We cannot generate a simple prefix if we would have to
+         * append a query string.
+         */
+        error_setg(errp,
+                   "Cannot generate a base directory with host_key_check set");
+        return NULL;
+    }
+
+    if (bs->exact_filename[0] == '\0') {
+        error_setg(errp, "Cannot generate a base directory for this ssh node");
+        return NULL;
+    }
+
+    return path_combine(bs->exact_filename, "");
+}
+
 static const char *const ssh_strong_runtime_opts[] = {
     "host",
     "port",
@@ -1322,6 +1342,7 @@ static BlockDriver bdrv_ssh = {
     .bdrv_co_truncate             = ssh_co_truncate,
     .bdrv_co_flush_to_disk        = ssh_co_flush,
     .bdrv_refresh_filename        = ssh_refresh_filename,
+    .bdrv_dirname                 = ssh_bdrv_dirname,
     .create_opts                  = &ssh_create_opts,
     .strong_runtime_opts          = ssh_strong_runtime_opts,
 };
-- 
2.20.1

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

* Re: [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename()
  2019-02-25 19:08 [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
  2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 1/2] " Max Reitz
  2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 2/2] block/ssh: Implement .bdrv_dirname() Max Reitz
@ 2019-04-13 16:26 ` Max Reitz
  2019-04-13 16:26   ` Max Reitz
  2 siblings, 1 reply; 5+ messages in thread
From: Max Reitz @ 2019-04-13 16:26 UTC (permalink / raw)
  To: qemu-block; +Cc: qemu-devel, Richard W . M . Jones, Kevin Wolf

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

On 25.02.19 20:08, Max Reitz wrote:
> This series implements .bdrv_refresh_filename() for the ssh block
> driver, along with an appropriate .bdrv_dirname() so we don't chop off
> query strings for backing files with relative filenames.
> 
> 
> v3:
> - Keep iotests 104 and 207 working
> 
> 
> Max Reitz (2):
>   block/ssh: Implement .bdrv_refresh_filename()
>   block/ssh: Implement .bdrv_dirname()
> 
>  block/ssh.c                   | 73 ++++++++++++++++++++++++++++++++---
>  tests/qemu-iotests/207        | 10 ++---
>  tests/qemu-iotests/207.out    | 10 ++---
>  tests/qemu-iotests/common.rc  |  2 +-
>  tests/qemu-iotests/iotests.py |  2 +-
>  5 files changed, 80 insertions(+), 17 deletions(-)
Applied to my block-next branch.

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename()
  2019-04-13 16:26 ` [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
@ 2019-04-13 16:26   ` Max Reitz
  0 siblings, 0 replies; 5+ messages in thread
From: Max Reitz @ 2019-04-13 16:26 UTC (permalink / raw)
  To: qemu-block; +Cc: Kevin Wolf, qemu-devel, Richard W . M . Jones

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

On 25.02.19 20:08, Max Reitz wrote:
> This series implements .bdrv_refresh_filename() for the ssh block
> driver, along with an appropriate .bdrv_dirname() so we don't chop off
> query strings for backing files with relative filenames.
> 
> 
> v3:
> - Keep iotests 104 and 207 working
> 
> 
> Max Reitz (2):
>   block/ssh: Implement .bdrv_refresh_filename()
>   block/ssh: Implement .bdrv_dirname()
> 
>  block/ssh.c                   | 73 ++++++++++++++++++++++++++++++++---
>  tests/qemu-iotests/207        | 10 ++---
>  tests/qemu-iotests/207.out    | 10 ++---
>  tests/qemu-iotests/common.rc  |  2 +-
>  tests/qemu-iotests/iotests.py |  2 +-
>  5 files changed, 80 insertions(+), 17 deletions(-)
Applied to my block-next branch.

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2019-04-13 16:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-25 19:08 [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 1/2] " Max Reitz
2019-02-25 19:08 ` [Qemu-devel] [PATCH v3 2/2] block/ssh: Implement .bdrv_dirname() Max Reitz
2019-04-13 16:26 ` [Qemu-devel] [PATCH v3 0/2] block/ssh: Implement .bdrv_refresh_filename() Max Reitz
2019-04-13 16:26   ` Max Reitz

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).