virt-sysprep as a Bash script
by Omar Aloraini
Hello,
Due to some complications, I couldn't run virt-sysprep on VMDK exported
from vDirector, the issue has to do with read only disk image and write
protection(there is a mention of a lock being held).
I gave up afterwards, and I'm looking for a Bash script that does the
'prep' part after the VM is created. I don't mind doing it manually from
the console, as I already have to configure networking.
I was looking at libugestfs source in github trying to find the steps to
effectively do what virt-sysprep is doing. But it's not clear where it's.
regards,
3 years, 3 months
[PATCH] spec: Clarify STARTTLS vs. SET_META_CONTEXT interaction
by Eric Blake
Consider a SELECTIVETLS server and a MitM attacker, under the
following NBD_OPT_ handshake scenario:
client: mitm: server:
> _STARTTLS
> _SET_META_CONTEXT("A")
< _REP_META_CONTEXT
< _REP_ACK
> _STARTTLS
< _REP_ACK
< _REP_ACK
> _SET_META_CONTEXT("B")
< _REP_META_CONTEXT
< _REP_ACK
> _GO
> _GO
< _REP_ACK
< _REP_ACK
> NBD_CMD_BLOCK_STATUS
While this scenario requires the MitM to be able to use encryption to
speak to the client (and thus a less likely scenario than a true
protocol downgrade or plaintext buffering attack), it results in a
situation where the client is asking for information on context "B",
but where the server only saw a request for context "A", which may
result in the client interpreting the results of BLOCK_STATUS
incorrectly even though it is coming over an encrypted connection.
The safest fix to this is to require that a server cannot use any meta
context requests from prior to enabling encryption with any successful
NBD_OPT_GO after encryption. At this point, the spec already states
that the server should then return an error (the client is asking for
block status without proper negotiation), which is better than letting
the client blindly misinterpret a response sent for a different meta
context.
To date, the only known server that has implemented TLS with
SELECTIVETLS mode as well as support for NBD_OPT_SET_META_CONTEXT is
nbdkit (qemu-nbd only has FORCEDTLS mode, and nbd-server lacks meta
context support); thankfully, that implementation is in already line
with this stricter requirement.
---
doc/proto.md | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/doc/proto.md b/doc/proto.md
index 61d57b5..7155b42 100644
--- a/doc/proto.md
+++ b/doc/proto.md
@@ -1165,6 +1165,14 @@ of the newstyle negotiation.
permitted by this document (for example, `NBD_REP_ERR_INVALID` if
the client included data).
+ When this command succeeds, the server MUST NOT preserve any
+ per-export state (such as metadata contexts from
+ `NBD_OPT_SET_META_CONTEXT`) issued before this command. The
+ server MAY preserve global state such as a client request for
+ `NBD_OPT_STRUCTURED_REPLY`; however, a client SHOULD defer other
+ stateful option requests until after it determines whether
+ encryption is available.
+
See the section on TLS above for further details.
* `NBD_OPT_INFO` (6) and `NBD_OPT_GO` (7)
@@ -1406,8 +1414,8 @@ of the newstyle negotiation.
negotiation phase it sent `NBD_OPT_SET_META_CONTEXT` at least
once, and where the final time it was sent, it referred to the
same export name that was ultimately selected for transmission
- phase, and where the server responded by returning least one
- metadata context without error.
+ phase with no intervening `NBD_OPT_STARTTLS`, and where the server
+ responded by returning least one metadata context without error.
Data:
- 32 bits, length of export name.
--
2.31.1
3 years, 3 months
[PATCH] spec: Clarify STARTTLS vs. STRUCTURED_REPLY
by Eric Blake
Consider a SELECTIVETLS server and a MitM attacker, under the
following NBD_OPT_ handshake scenario:
client: mitm: server:
> _STARTTLS
> _STRUCTURED_REPLY
< _REP_ACK
> _STARTTLS
< _REP_ACK
< _REP_ACK
> _GO
> _GO
< _REP_ACK
< _REP_ACK
> NBD_CMD_READ
In this scenario, the client is NOT expecting structured replies from
the server, but if the server feels obligated to send them based on
the plaintext negotiation, it may confuse the client. The MitM
attacker was thus able to corrupt the connection, even without having
any encryption keys. The only sane approach is to forbid ALL stateful
negotiations from having any effect post-encryption (the MitM's
injected packet is effectively ignored, and the client proceeds
without structured replies).
Unfortunately, nbdkit 1.26.0 is buggy in this regards - a CVE will be
opened against that product. nbd-server does not yet understand
NBD_OPT_STRUCTURED_REPLY, and qemu as server does not use SELECTIVETLS
mode, so they are immune.
---
doc/proto.md | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/doc/proto.md b/doc/proto.md
index de4a7d7..9dd59da 100644
--- a/doc/proto.md
+++ b/doc/proto.md
@@ -1166,12 +1166,11 @@ of the newstyle negotiation.
the client included data).
When this command succeeds, the server MUST NOT preserve any
- per-export state (such as metadata contexts from
- `NBD_OPT_SET_META_CONTEXT`) issued before this command. The
- server MAY preserve global state such as a client request for
- `NBD_OPT_STRUCTURED_REPLY`; however, a client SHOULD defer
- stateful option requests until after it determines whether
- encryption is available.
+ negotiation state (such as a request for
+ `NBD_OPT_STRUCTURED_REPLY`, or metadata contexts from
+ `NBD_OPT_SET_META_CONTEXT`) issued before this command. A client
+ SHOULD defer all stateful option requests until after it
+ determines whether encryption is available.
See the section on TLS above for further details.
@@ -1317,6 +1316,10 @@ of the newstyle negotiation.
client MUST NOT make use of those extensions without first
enabling the `NBD_OPT_STRUCTURED_REPLY` extension.
+ If the client requests `NBD_OPT_STARTTLS` after this option, it
+ MUST renegotiate structured replies and any other dependent
+ extensions that it desires to use.
+
* `NBD_OPT_LIST_META_CONTEXT` (9)
Return a list of `NBD_REP_META_CONTEXT` replies, one per context,
--
2.31.1
3 years, 3 months
[libnbd PATCH] tests: Prefer qemu-nbd --cache=writeback
by Eric Blake
QEMU 6.1 and earlier default qemu-img to --cache=writeback, but
qemu-nbd to --cache=writethrough, which is inherently slower because
it requires more flushing. Although qemu 6.2 will probably be
changing the default of qemu-nbd for consistency, in the meantime we
can be explicit in our choice for slightly faster testing.
Tests that only read from the image are not altered, as the slowdowns
really only impact writing to qemu-nbd. Documentation examples were
not updated, because there we can just wait for new-enough qemu-nbd
with saner defaults.
Based on a qemu-nbd report by Nir Soffer.
---
copy/copy-file-to-qcow2.sh | 2 +-
fuse/test-qcow2.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/copy/copy-file-to-qcow2.sh b/copy/copy-file-to-qcow2.sh
index dfd870b..24a0ce9 100755
--- a/copy/copy-file-to-qcow2.sh
+++ b/copy/copy-file-to-qcow2.sh
@@ -54,7 +54,7 @@ qemu-img create -f qcow2 $qcow2 $size
# Run qemu-nbd as a separate process so that we can copy to and from
# the single process in two separate operations.
-$QEMU_NBD -f qcow2 -t --socket=$sock --pid-file=$pidfile $qcow2 &
+$QEMU_NBD -f qcow2 --cache=writeback -t --socket=$sock --pid-file=$pidfile $qcow2 &
cleanup_fn kill $!
wait_for_pidfile qemu-nbd $pid
diff --git a/fuse/test-qcow2.sh b/fuse/test-qcow2.sh
index 0545d1d..3bf365c 100755
--- a/fuse/test-qcow2.sh
+++ b/fuse/test-qcow2.sh
@@ -48,7 +48,7 @@ qemu-img convert -f raw $data -O qcow2 $qcow2
rm -rf $mp
mkdir -p $mp
-$VG nbdfuse -r -P $pidfile $mp [ qemu-nbd -f qcow2 $qcow2 ] &
+$VG nbdfuse -r -P $pidfile $mp [ qemu-nbd -f qcow2 --cache=writeback $qcow2 ] &
# Wait for the pidfile to appear.
for i in {1..60}; do
--
2.31.1
3 years, 3 months
Re: [Libguestfs] [libguestfs/libguestfs] guestunmount should not return before the image can be used by other vm (#70)
by Richard W.M. Jones
On Wed, Aug 11, 2021 at 01:21:18AM -0700, braindevices wrote:
> If I understood correct, the libguestfs actually start a qemu vm under the
> hood. When I call guestunmount it unmounts the image then shutdown the vm.
> However, if I do this programmably, commonly it will fail due to the vm is
> still using the image:
>
> guestmount -d guest1 mnt
> # do something with the image
> guestunmount mnt
> virsh start guest1
>
> I have to add sleep between guestunmount and other command. However,
> this time interval is not certain, it can be quite long at some
> time. So I propose to add some option to let the guestunmount only
> return after the qemu vm release the image. Is there any work around
> right now for this?
If the libvirt configuration uses cache=none, you could be hitting
this:
https://github.com/rwmjones/guestfs-tools/blob/9ba463545fa017910a5077434f...
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
3 years, 3 months
[PATCH nbdkit 1/3] server: nanosleep: Change error for early end of sleep
by Richard W.M. Jones
At the moment nbdkit_nanosleep gives an incorrect error message if it
aborts early. Even in the case when the server is not actually
shutting down it will say:
$ nbdkit --filter=delay null delay-close=3 --run 'nbdinfo --size $uri; nbdinfo --size $uri'
0
nbdkit: null[1]: error: aborting sleep to shut down
0
nbdkit: null[2]: error: aborting sleep to shut down
This commit changes the error so we only talk about shut down when the
server is actually shutting down, and use a different message in other
cases.
---
server/public.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/server/public.c b/server/public.c
index 4870e2d3..d9ed0d9c 100644
--- a/server/public.c
+++ b/server/public.c
@@ -728,7 +728,10 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
(conn && conn->nworkers > 0 && connection_get_status () < 1) ||
(conn && (fds[2].revents & (POLLRDHUP | POLLHUP | POLLERR |
POLLNVAL))));
- nbdkit_error ("aborting sleep to shut down");
+ if (quit)
+ nbdkit_error ("aborting sleep because of server shut down");
+ else
+ nbdkit_error ("aborting sleep because of connection close or error");
errno = ESHUTDOWN;
return -1;
--
2.32.0
3 years, 3 months
[nbdkit PATCH] maint: Default to probing valgrind at runtime
by Eric Blake
When we added --enable-valgrind in commit ac4ad5545, we argued that a
runtime probe for valgrind might be invasive enough that it should be
opt-in for developers only. But it turns out that valgrind.h's
implementation for RUNNING_ON_VALGRIND is intentionally minimally
invasive: it does not link in any external library or function calls,
but merely injects a few benign instructions (a sequence of rol on
x86_64) that the valgrind JIT recognizes as special, but which are a
no-op on bare-metal runs. Furthermore, we are not checking valgrind
use in a hotspot. So there is no real penalty to defaulting the
valgrind probe to on, which makes 'make check-valgrind' more likely to
work out-of-the-box. Still, we keep --disable-valgrind for anyone
that does not want to use 'CFLAGS=-DNVALGRIND' as another alternative
for avoiding even those few assembly instructions in a production
binary.
Also, we misused AC_ARG_ENABLE, such that './configure
--disable-valgrind' actually enables valgrind. We then copied that
same bug for --disable-libfuzzer (commit 9b0300ca). An audit of the
other AC_ARG_WITH and AC_ARG_ENABLE did not find other instances of
this misuse.
In addition to tweaking the configure default, we need to rearrange
the logic of internal.h so that libfuzzer and sanitize address still
unconditionally disable dlclose, even when valgrind headers were
detected.
---
configure.ac | 20 +++++++++++---------
server/internal.h | 14 ++++++++------
2 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index a813dfff..ef9c99b4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -638,20 +638,22 @@ dnl Check for valgrind.
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind],[no])
dnl If valgrind headers are available (optional).
-dnl Since this is only useful for developers, you have to enable
-dnl it explicitly using --enable-valgrind.
+dnl Although the runtime check adds only a trivial amount of code, you can
+dnl avoid it with explicit --disable-valgrind.
AC_ARG_ENABLE([valgrind],
- [AS_HELP_STRING([--enable-valgrind],
- [enable Valgrind extensions (for developers)])],
- [enable_valgrind=yes],
- [enable_valgrind=no])
-AS_IF([test "x$enable_valgrind" = "xyes"],[
+ [AS_HELP_STRING([--disable-valgrind],
+ [disable Valgrind probe])],
+ [],
+ [enable_valgrind=check])
+AS_IF([test "x$enable_valgrind" != "xno"],[
PKG_CHECK_MODULES([VALGRIND], [valgrind], [
AC_SUBST([VALGRIND_CFLAGS])
AC_SUBST([VALGRIND_LIBS])
AC_DEFINE([HAVE_VALGRIND],[1],[Valgrind headers found at compile time])
],[
- AC_MSG_ERROR([--enable-valgrind given, but Valgrind headers are not available])
+ AS_IF([test "x$enable_valgrind" = "xyes"], [
+ AC_MSG_ERROR([--enable-valgrind given, but Valgrind headers are not available])
+ ])
])
])
@@ -660,7 +662,7 @@ dnl normal builds. See fuzzing/README.
AC_ARG_ENABLE([libfuzzer],
[AS_HELP_STRING([--enable-libfuzzer],
[build libFuzzer test binary (developers only)])],
- [enable_libfuzzer=yes],
+ [],
[enable_libfuzzer=no])
AS_IF([test "x$enable_libfuzzer" = "xyes"],[
AC_DEFINE([ENABLE_LIBFUZZER],[1],[Enable special libFuzzer binary])
diff --git a/server/internal.h b/server/internal.h
index b1473911..bc81b786 100644
--- a/server/internal.h
+++ b/server/internal.h
@@ -63,11 +63,7 @@
#define if_verbose if (verbose)
#endif
-#if HAVE_VALGRIND
-# include <valgrind.h>
-/* http://valgrind.org/docs/manual/faq.html#faq.unhelpful */
-# define DO_DLCLOSE !RUNNING_ON_VALGRIND
-#elif defined(__SANITIZE_ADDRESS__)
+#if defined(__SANITIZE_ADDRESS__)
# define DO_DLCLOSE 0
#elif ENABLE_LIBFUZZER
/* XXX This causes dlopen in the server to leak during fuzzing.
@@ -76,7 +72,13 @@
*/
# define DO_DLCLOSE 0
#else
-# define DO_DLCLOSE 1
+# if HAVE_VALGRIND
+# include <valgrind.h>
+/* http://valgrind.org/docs/manual/faq.html#faq.unhelpful */
+# define DO_DLCLOSE !RUNNING_ON_VALGRIND
+# else
+# define DO_DLCLOSE 1
+# endif
#endif
/* Declare program_name. */
--
2.31.1
3 years, 3 months
[PATCH nbdkit] server: Return from nbdkit_nanosleep early if the socket closes
by Richard W.M. Jones
https://bugzilla.redhat.com/show_bug.cgi?id=1991652#c2
Reported-by: Ming Xie
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1991652
---
server/public.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/server/public.c b/server/public.c
index 3362f1ab..30fb5aa0 100644
--- a/server/public.c
+++ b/server/public.c
@@ -693,6 +693,8 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
* - the current connection is multi-threaded and another thread detects
* NBD_CMD_DISC or a problem with the connection
* - the input socket detects POLLRDHUP/POLLHUP/POLLERR
+ * - the input socket is invalid (POLLNVAL, probably closed by
+ * another thread)
*/
struct connection *conn = threadlocal_get_conn ();
struct pollfd fds[] = {
@@ -724,7 +726,8 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
*/
assert (quit ||
(conn && conn->nworkers > 0 && connection_get_status () < 1) ||
- (conn && (fds[2].revents & (POLLRDHUP | POLLHUP | POLLERR))));
+ (conn && (fds[2].revents & (POLLRDHUP | POLLHUP |
+ POLLERR | POLLNVAL))));
nbdkit_error ("aborting sleep to shut down");
errno = ESHUTDOWN;
return -1;
--
2.32.0
3 years, 3 months
[nbdkit PATCH v2] tests: Check that cache-min-block-size works properly
by Martin Kletzander
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
tests/test-cache-block-size.sh | 41 +++++++++++++++++++++-------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/tests/test-cache-block-size.sh b/tests/test-cache-block-size.sh
index d20cc94002b6..403c295e57c9 100755
--- a/tests/test-cache-block-size.sh
+++ b/tests/test-cache-block-size.sh
@@ -43,28 +43,39 @@ rm -f $files
cleanup_fn rm -f $files
# Create an empty base image.
-truncate -s 128K cache-block-size.img
+truncate -s 256K cache-block-size.img
# Run nbdkit with the caching filter.
start_nbdkit -P cache-block-size.pid -U $sock --filter=cache \
- file cache-block-size.img cache-min-block-size=4K
+ file cache-block-size.img cache-min-block-size=128K \
+ cache-on-read=true
nbdsh --connect "nbd+unix://?socket=$sock" \
-c '
-# Write some pattern data to the overlay and check it reads back OK.
-buf = b"abcd" * 16384
-h.pwrite(buf, 32768)
-zero = h.pread(32768, 0)
-assert zero == bytearray(32768)
-buf2 = h.pread(65536, 32768)
-assert buf == buf2
+# Read half of cache-min-block-size
+
+zero = h.pread(64 * 1024, 0)
+assert zero == bytearray(64 * 1024)
+
+buf = b"abcd" * 16 * 1024
-# Flushing should write through to the underlying file.
-h.flush()
+# Write past the first read
+with open("cache-block-size.img", "wb") as file:
+ file.seek(64 * 1024)
+ file.write(buf * 2)
+ file.truncate(256 * 1024)
+# Check that it got written
with open("cache-block-size.img", "rb") as file:
- zero = file.read(32768)
- assert zero == bytearray(32768)
- buf2 = file.read(65536)
- assert buf == buf2
+ file.seek(64 * 1024)
+ buf2 = file.read(128 * 1024)
+ assert (buf * 2) == buf2
+
+# Now read the rest of the cache-min-block-size, it should stay empty
+zero = h.pread(64 * 1024, 64 * 1024)
+assert zero == bytearray(64 * 1024)
+
+# Read past that, the pattern should be visible there
+buf2 = h.pread(64 * 1024, 128 * 1024)
+assert buf == buf2
'
--
2.32.0
3 years, 3 months
[nbdkit PATCH] tests: Check that cache-min-block-size works properly
by Martin Kletzander
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
tests/test-cache-block-size.sh | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/tests/test-cache-block-size.sh b/tests/test-cache-block-size.sh
index d20cc94002b6..5e83ebc1cfaa 100755
--- a/tests/test-cache-block-size.sh
+++ b/tests/test-cache-block-size.sh
@@ -47,24 +47,35 @@ truncate -s 128K cache-block-size.img
# Run nbdkit with the caching filter.
start_nbdkit -P cache-block-size.pid -U $sock --filter=cache \
- file cache-block-size.img cache-min-block-size=4K
+ file cache-block-size.img cache-min-block-size=64K \
+ cache-on-read=true
nbdsh --connect "nbd+unix://?socket=$sock" \
-c '
-# Write some pattern data to the overlay and check it reads back OK.
-buf = b"abcd" * 16384
-h.pwrite(buf, 32768)
+# Read half of cache-min-block-size
+
zero = h.pread(32768, 0)
assert zero == bytearray(32768)
-buf2 = h.pread(65536, 32768)
-assert buf == buf2
-# Flushing should write through to the underlying file.
-h.flush()
+buf = b"abcd" * 8192
+# Write past the first read
+with open("cache-block-size.img", "wb") as file:
+ file.seek(32768)
+ file.write(buf * 2)
+ file.truncate(131072)
+
+# Check that it got written
with open("cache-block-size.img", "rb") as file:
- zero = file.read(32768)
- assert zero == bytearray(32768)
+ file.seek(32768)
buf2 = file.read(65536)
- assert buf == buf2
+ assert (buf * 2) == buf2
+
+# Now read the rest of the cache-min-block-size, it should stay empty
+zero = h.pread(32768, 32768)
+assert zero == bytearray(32768)
+
+# Read past that, the pattern should be visible there
+buf2 = h.pread(32768, 65536)
+assert buf == buf2
'
--
2.32.0
3 years, 3 months