[PATCH v2] lib, lua: Fix usage of strerror_r
by Richard W.M. Jones
$ ./run guestfish -vx add-drive foo "readonly:true"
libguestfs: trace: set_pgroup true
libguestfs: trace: set_pgroup = 0
libguestfs: trace: add_drive "foo" "readonly:true"
libguestfs: error: foo:
libguestfs: trace: add_drive = -1 (error)
libguestfs: trace: close
libguestfs: closing guestfs handle 0x55c0bacf12a0 (state 0)
Fix the usage of strerror_r by using the new wrapper defined in
libguestfs-common. A similar fix is made in the Lua bindings.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2030396
Reported-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
Tested-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
---
common | 2 +-
generator/lua.ml | 18 ++++++++----------
lib/errors.c | 7 ++++---
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/common b/common
index a405dc599e..8fcdc2c6a1 160000
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit a405dc599e571410b83d145d02705708e1715e94
+Subproject commit 8fcdc2c6a1e438012aaa24c58fa06f9d1efc6b93
diff --git a/generator/lua.ml b/generator/lua.ml
index 7b05c72e7a..0d7e63be0f 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -164,10 +164,9 @@ guestfs_int_lua_create (lua_State *L)
return luaL_error (L, \"Guestfs.create: too many arguments\");
g = guestfs_create_flags (flags);
- if (!g) {
- ignore_value (strerror_r (errno, err, sizeof err));
- return luaL_error (L, \"Guestfs.create: cannot create handle: %%s\", err);
- }
+ if (!g)
+ return luaL_error (L, \"Guestfs.create: cannot create handle: %%s\",
+ guestfs_int_strerror (errno, err, sizeof err));
guestfs_set_error_handler (g, NULL, NULL);
@@ -243,10 +242,9 @@ error__tostring (lua_State *L)
lua_gettable (L, 1);
msg = luaL_checkstring (L, -1);
- if (code) {
- ignore_value (strerror_r (code, err, sizeof err));
- lua_pushfstring (L, \"%%s: %%s\", msg, err);
- }
+ if (code)
+ lua_pushfstring (L, \"%%s: %%s\", msg,
+ guestfs_int_strerror (code, err, sizeof err));
else
lua_pushstring (L, msg);
@@ -655,8 +653,8 @@ get_string_list (lua_State *L, int index)
strs = malloc ((len+1) * sizeof (char *));
if (strs == NULL) {
- ignore_value (strerror_r (errno, err, sizeof err));
- luaL_error (L, \"get_string_list: malloc failed: %%s\", err);
+ luaL_error (L, \"get_string_list: malloc failed: %%s\",
+ guestfs_int_strerror (errno, err, sizeof err));
/*NOTREACHED*/
return NULL;
}
diff --git a/lib/errors.c b/lib/errors.c
index bd9699eeb1..285209e44e 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -322,6 +322,7 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...)
const int errnum = errno;
int err;
char buf[256];
+ const char *errstr;
struct error_data *error_data = get_error_data (g);
va_start (args, fs);
@@ -330,11 +331,11 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...)
if (err < 0) return;
- ignore_value (strerror_r (errnum, buf, sizeof buf));
+ errstr = guestfs_int_strerror (errnum, buf, sizeof buf);
- msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
+ msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (errstr) + 1);
strcat (msg, ": ");
- strcat (msg, buf);
+ strcat (msg, errstr);
/* set_last_error first so that the callback can access the error
* message and errno through the handle if it wishes.
--
2.32.0
3 years
[PATCH] lib/errors.c: Fix usage of strerror_r
by Richard W.M. Jones
$ ./run guestfish -vx add-drive foo "readonly:true"
libguestfs: trace: set_pgroup true
libguestfs: trace: set_pgroup = 0
libguestfs: trace: add_drive "foo" "readonly:true"
libguestfs: error: foo:
libguestfs: trace: add_drive = -1 (error)
libguestfs: trace: close
libguestfs: closing guestfs handle 0x55c0bacf12a0 (state 0)
Note the "error: foo: " line. After hexdumping this I found that it
is actually printing random rubbish after the colon. It turns out
that strerror_r was not updating the buffer and so we were printing
random bytes from the stack.
strerror_r is hard to use and worse still there are two incompatible
variants in glibc. Close reading of the GNU variant that we are using
shows that it doesn't always use the buffer passed in, which explains
what was happening here.
Try to fix usage of strerror_r and try to cope with the two variants
using _GNU_SOURCE.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2030396
---
lib/errors.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/lib/errors.c b/lib/errors.c
index bd9699eeb1..d599a21879 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -322,6 +322,7 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...)
const int errnum = errno;
int err;
char buf[256];
+ const char *errstr;
struct error_data *error_data = get_error_data (g);
va_start (args, fs);
@@ -330,11 +331,19 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...)
if (err < 0) return;
- ignore_value (strerror_r (errnum, buf, sizeof buf));
+#ifdef _GNU_SOURCE
+ /* GNU strerror_r */
+ errstr = strerror_r (errnum, buf, sizeof buf);
+#else
+ /* XSI-compliant strerror_r */
+ err = strerror_r (errnum, buf, sizeof buf);
+ if (err > 0) return;
+ errstr = buf;
+#endif
- msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
+ msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (errstr) + 1);
strcat (msg, ": ");
- strcat (msg, buf);
+ strcat (msg, errstr);
/* set_last_error first so that the callback can access the error
* message and errno through the handle if it wishes.
--
2.32.0
3 years
guestfs-tools for *BSD images
by Brady Pratt
Hi!
I'm curious about general support for BSD flavors with the guestfs-tools
and any history behind this. I've read through small bits of the code, and
from what I can tell certain commands aren't going to be supported
(install[0], update, uninstall) but maybe some will "just work" such as
inject-ssh[1] or password?
I've been attempting to set a user password for an OpenBSD 6.9 image[2],
but I'm met with an error related to mounting (ufs). Embarrassingly, and
while the error is very clear, I don't understand how to resolve this or if
I'm trying to achieve something that doesn't work. I've tried adding
`--mount-options` but I can't tell if these are getting propagated down.
```
$ virt-sysprep -v --add openbsd-6.9.qcow2 --password
openbsd:password:openbsd
...
command: mount '/dev/sda4' '/sysroot//'
[ 1.997492] ufs: ufs was compiled with read-only support, can't be
mounted as read-write
[ 1.998352] ufs: You didn't specify the type of your ufs filesystem
[ 1.998352]
[ 1.998352] mount -t ufs -o
ufstype=sun|sunx86|44bsd|ufs2|5xbsd|old|hp|nextstep|nextstep-cd|openstep ...
[ 1.998352]
[ 1.998352] >>>WARNING<<< Wrong ufstype may corrupt your filesystem,
default is ufstype=old
[ 2.001713] ufs: ufs_fill_super(): bad magic number
command: mount returned 32
command: mount: stderr:
mount: /sysroot: wrong fs type, bad option, bad superblock on /dev/sda4,
missing codepage or helper program, or other error.
ocaml_exn: 'mount_options' raised 'Failure' exception
guestfsd: error: mount exited with status 32: mount: /sysroot: wrong fs
type, bad option, bad superblock on /dev/sda4, missing codepage or helper
program, or other error.
guestfsd: => mount_options (0x4a) took 0.02 secs
virt-sysprep: warning: mount_options: mount exited with status 32: mount:
/sysroot: wrong fs type, bad option, bad superblock on /dev/sda4, missing
codepage or helper program, or other error. (ignored)
[ 2.3] Performing "abrt-data" ...
guestfsd: <= inspect_get_type (0x1e3) request length 56 bytes
commandrvf: stdout=n stderr=y flags=0x0
commandrvf: udevadm --debug settle -E /dev/sda4
SELinux enabled state cached to: disabled
No filesystem is currently mounted on /sys/fs/cgroup.
Failed to determine unit we run in, ignoring: No data available
guestfsd: => inspect_get_type (0x1e3) took 0.01 secs
guestfsd: <= glob_expand (0x71) request length 68 bytes
guestfsd: error: glob_expand_stub: you must call 'mount' first to mount the
root filesystem
guestfsd: => glob_expand (0x71) took 0.00 secs
virt-sysprep: error: libguestfs error: glob_expand: glob_expand_stub: you
must call 'mount' first to mount the root filesystem
If reporting bugs, run virt-sysprep with debugging enabled and include the
complete output:
virt-sysprep -v -x [...]
libguestfs: closing guestfs handle 0x555ea1442800 (state 2)
...
```
This brings me to asking if there is any desire to support BSD flavors, has
it been done in the past and removed, or is it even feasible? I would
imagine this has already been explored and I'm just failing to find the
mail thread explaining things. If anyone has any experience doing this or
advice, I would really appreciate it. I'm incredibly new to all of this, my
apologies if this seems dumb or a waste of time.
Thank you kindly for any assistance on the matter,
Brady Pratt
[0]:
https://github.com/rwmjones/guestfs-tools/blob/master/customize/customize...
[1]:
https://github.com/rwmjones/guestfs-tools/blob/3a498512f58bc431db490e96cd...
[2]: https://bsd-cloud-image.org/
3 years
[virt-v2v PATCH 0/3] lib/create_ovf: populate "actual size" attributes again
by Laszlo Ersek
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2027598
With the modularization of virt-v2v, determining the host disk
allocation of copied (= output) VM disk images became more difficult,
and so we dropped the following attributes from the generated OVF files:
- ovf:Envelope/References/File/@ovf:size
- ovf:Envelope/Section[@xsi:type='ovf:DiskSection_Type']/Disk/@ovf:actual_size
Right now we have an "XXX" reminder in the code.
Unfortunately, ovirt-engine really insists on the presence of the
"ovf:actual_size" attribute -- there used to be a nullity check
regarding the attribute, but it was regressed in ovirt-engine commit
commit 1082d9dec289 ("core: undo recent generalization of ovf
processing", 2017-08-09). Therefore, as of commit a2e74bdb3fe1 ("core:
test network stats with big integer values", 2021-12-07), ovirt-engine
rejects our OVF files, and we must generate "ovf:actual_size" even if we
don't have the necessary info for it -- that is, with empty contents.
This patch series implements -- based on Rich's NBD demo code he had
sent me off-list -- the necessary "du"-like logic on the output disks
using NBD APIs.
Thanks,
Laszlo
Laszlo Ersek (3):
lib/nbdkit: add the "Nbdkit.with_connect_unix" helper function
lib/nbdkit: add the "Nbdkit.get_disk_allocated" helper function
lib/create_ovf: populate "actual size" attributes again
lib/Makefile.am | 2 +-
lib/create_ovf.ml | 33 +++++++--------
lib/create_ovf.mli | 2 +-
lib/nbdkit.ml | 42 ++++++++++++++++++++
lib/nbdkit.mli | 18 +++++++++
output/output_rhv.ml | 2 +-
output/output_rhv_upload.ml | 2 +-
output/output_vdsm.ml | 1 +
tests/test-v2v-o-rhv.ovf.expected | 4 +-
tests/test-v2v-o-vdsm-options.ovf.expected | 4 +-
10 files changed, 84 insertions(+), 26 deletions(-)
base-commit: bb0e698360470cb4ff5992e8e01a3165f56fe41e
--
2.19.1.3.g30247aa5d201
3 years
[PATCH nbdkit] file: Fix implementation of cache=none for writes
by Richard W.M. Jones
When testing virt-v2v we found that cache=none had very pessimal
performance in its current implementation when writing. See:
https://github.com/libguestfs/virt-v2v/commit/ac59d3b2310511b1537d408b675...
However we know of a much better implementation - the one in nbdcopy.
This commit copies that implementation (for writes only).
A simple test is to do:
$ ./nbdkit file out.img cache=none --run 'nbdcopy fedora-33.img $uri'
and then check the cache usage of the output file, which should be
around 0% (using https://github.com/Feh/nocache):
$ cachestats out.img
pages in cache: 409/1572864 (0.0%) [filesize=6291456.0K, pagesize=4K]
For modular virt-v2v doing a local disk to local disk conversion:
- before this change, without cache=none
virt-v2v took 93.7 seconds, 19.1% pages cached in output file
- before this change, enabling cache=none
virt-v2v took 125.4 seconds, 0.0% pages cached in output file
^^^ this is the bad case which caused the investigation
- after this change, without cache=none
virt-v2v took 93.2 seconds, 19.1% pages cached in output file
- after this change, enabling cache=none
virt-v2v took 97.9 seconds, 0.1% pages cached in output file
I tried to adjust NR_WINDOWS to find an optimum. Increasing it made
no difference in performance but predictably caused a slight increase
in cached pages. Reducing it slowed performance slightly. So I
conclude that 8 is about right, but it probably depends on the
hardware.
---
plugins/file/nbdkit-file-plugin.pod | 3 ++
plugins/file/file.c | 79 +++++++++++++++++++++++++----
2 files changed, 72 insertions(+), 10 deletions(-)
diff --git a/plugins/file/nbdkit-file-plugin.pod b/plugins/file/nbdkit-file-plugin.pod
index 0ac0ee53..f8f0e198 100644
--- a/plugins/file/nbdkit-file-plugin.pod
+++ b/plugins/file/nbdkit-file-plugin.pod
@@ -117,6 +117,9 @@ cache:
nbdkit file disk.img fadvise=sequential cache=none
+Only use fadvise=sequential if reading, and the reads are mainly
+sequential.
+
=head2 Files on tmpfs
If you want to expose a file that resides on a file system known to
diff --git a/plugins/file/file.c b/plugins/file/file.c
index 35270a24..caf24b2c 100644
--- a/plugins/file/file.c
+++ b/plugins/file/file.c
@@ -85,6 +85,69 @@ static int fadvise_mode =
/* cache mode */
static enum { cache_default, cache_none } cache_mode = cache_default;
+/* Define EVICT_WRITES if we are going to evict the page cache
+ * (cache=none) after writing. This is only known to work on Linux.
+ */
+#ifdef __linux__
+#define EVICT_WRITES 1
+#endif
+
+#ifdef EVICT_WRITES
+/* Queue writes so they will be evicted from the cache. See
+ * libnbd.git copy/file-ops.c for the rationale behind this.
+ */
+#define NR_WINDOWS 8
+
+struct write_window {
+ int fd;
+ uint64_t offset;
+ size_t len;
+};
+
+static pthread_mutex_t window_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct write_window window[NR_WINDOWS];
+
+static void
+evict_writes (int fd, uint64_t offset, size_t len)
+{
+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_lock);
+
+ /* Evict the oldest window from the page cache. */
+ if (window[0].len > 0) {
+ sync_file_range (window[0].fd, window[0].offset, window[0].len,
+ SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|
+ SYNC_FILE_RANGE_WAIT_AFTER);
+ posix_fadvise (window[0].fd, window[0].offset, window[0].len,
+ POSIX_FADV_DONTNEED);
+ }
+
+ /* Move the Nth window to N-1. */
+ memmove (&window[0], &window[1], sizeof window[0] * (NR_WINDOWS-1));
+
+ /* Set up the current window and tell Linux to start writing it out
+ * to disk (asynchronously).
+ */
+ sync_file_range (fd, offset, len, SYNC_FILE_RANGE_WRITE);
+ window[NR_WINDOWS-1].fd = fd;
+ window[NR_WINDOWS-1].offset = offset;
+ window[NR_WINDOWS-1].len = len;
+}
+
+/* When we close the handle we must remove any windows which are still
+ * associated. They missed the boat, oh well :-(
+ */
+static void
+remove_fd_from_window (int fd)
+{
+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_lock);
+ size_t i;
+
+ for (i = 0; i < NR_WINDOWS; ++i)
+ if (window[i].len > 0 && window[i].fd == fd)
+ window[i].len = 0;
+}
+#endif /* EVICT_WRITES */
+
/* Any callbacks using lseek must be protected by this lock. */
static pthread_mutex_t lseek_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -431,6 +494,9 @@ file_close (void *handle)
{
struct handle *h = handle;
+#ifdef EVICT_WRITES
+ remove_fd_from_window (h->fd);
+#endif
close (h->fd);
free (h);
}
@@ -583,15 +649,9 @@ file_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
{
struct handle *h = handle;
-#if defined (HAVE_POSIX_FADVISE) && defined (POSIX_FADV_DONTNEED)
+#if EVICT_WRITES
uint32_t orig_count = count;
uint64_t orig_offset = offset;
-
- /* If cache=none we want to force pages we have just written to the
- * file to be flushed to disk so we can immediately evict them from
- * the page cache.
- */
- if (cache_mode == cache_none) flags |= NBDKIT_FLAG_FUA;
#endif
while (count > 0) {
@@ -608,10 +668,9 @@ file_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
if ((flags & NBDKIT_FLAG_FUA) && file_flush (handle, 0) == -1)
return -1;
-#if defined (HAVE_POSIX_FADVISE) && defined (POSIX_FADV_DONTNEED)
- /* On Linux this will evict the pages we just wrote from the page cache. */
+#if EVICT_WRITES
if (cache_mode == cache_none)
- posix_fadvise (h->fd, orig_offset, orig_count, POSIX_FADV_DONTNEED);
+ evict_writes (h->fd, orig_offset, orig_count);
#endif
return 0;
--
2.32.0
3 years
[PATCH v2v] input: Disable multi-conn in VDDK input mode
by Richard W.M. Jones
I already pushed this commit, but I'm sending it to the list because
it reveals an interesting and unexpected side effect of
nbdkit-cow-filter (see commit message).
I wonder if we want to add a cow-multi-conn=false flag?
Rich.
3 years
[libnbd PATCH] maint: Suggest better diff output for API.ml
by Eric Blake
Git diff is able to customize the regex used to locate "function
headers", or the text to output on @@ lines of a patch to make it
easier to determine which portion of a file the patch touches. This
is done by coupling .gitattributes contents with the user running the
right 'git config' command. We don't have a bootstrap script, so we
don't have an automated place to forcefully ensure the right setup for
new contributors, but we can at least document the steps a developer
can do to make our lives easier.
For the API.ml file, not only do we want to highlight typical
top-level OCaml 'let' statements, we also want to highlight the start
of each of our API definitions.
Thanks: Laszlo Ersek <lersek(a)redhat.com>
---
.gitattributes | 3 +++
README | 4 ++++
2 files changed, 7 insertions(+)
create mode 100644 .gitattributes
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..cf630ae9
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+# Use the following one-time config to get nicer API diffs:
+# git config diff.api.xfuncname '^(let .*=| "[^"]*", \{$)'
+API.ml diff=api
diff --git a/README b/README
index 6502e7fc..8955f817 100644
--- a/README
+++ b/README
@@ -168,6 +168,10 @@ When testing use:
make check
make check-valgrind
+Use the following one-time setup for nicer diffs:
+
+ git config diff.api.xfuncname '^(let .*=| "[^"]*", \{$)'
+
For development ideas, see the TODO file.
The upstream git repository is:
--
2.33.1
3 years
[libnbd PATCH] docs: Mention explicit and inherent limits on lengths
by Eric Blake
Prior to implementing an NBD extension that will allow some commands
to accept a 64-bit count, it is worth documenting places where there
are 32-bit inherent limits, as well as where libnbd itself enforces a
smaller arbitrary limit, in spite of the API having a size_t or
uint64_t parameter.
---
generator/API.ml | 45 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/generator/API.ml b/generator/API.ml
index 602f51e0..cf2e7543 100644
--- a/generator/API.ml
+++ b/generator/API.ml
@@ -1,6 +1,6 @@
(* hey emacs, this is OCaml code: -*- tuareg -*- *)
(* nbd client library in userspace: the API
- * Copyright (C) 2013-2020 Red Hat Inc.
+ * Copyright (C) 2013-2021 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1822,6 +1822,12 @@ error. See also L<nbd_pread_structured(3)>, if finer visibility is
required into the server's replies, or if you want to use
C<LIBNBD_CMD_FLAG_DF>.
+Note that libnbd currently enforces a maximum read buffer of 64MiB,
+even if the server would permit a larger buffer in a single transaction;
+attempts to exceed this will result in an C<ERANGE> error. The server
+may enforce a smaller limit, which can be learned with
+L<nbd_get_block_size(3)>.
+
The C<flags> parameter must be C<0> for now (it exists for future NBD
protocol extensions)."
^ strict_call_description;
@@ -1898,6 +1904,12 @@ the server obeyed the requirement that a read call must not have
overlapping chunks and must not succeed without enough chunks to cover
the entire request.
+Note that libnbd currently enforces a maximum read buffer of 64MiB,
+even if the server would permit a larger buffer in a single transaction;
+attempts to exceed this will result in an C<ERANGE> error. The server
+may enforce a smaller limit, which can be learned with
+L<nbd_get_block_size(3)>.
+
The C<flags> parameter may be C<0> for no flags, or may contain
C<LIBNBD_CMD_FLAG_DF> meaning that the server should not reply with
more than one fragment (if that is supported - some servers cannot do
@@ -1924,6 +1936,12 @@ using this call. The call returns when the command has been
acknowledged by the server, or there is an error. Note this will
generally return an error if L<nbd_is_read_only(3)> is true.
+Note that libnbd currently enforces a maximum write buffer of 64MiB,
+even if the server would permit a larger buffer in a single transaction;
+attempts to exceed this will result in an C<ERANGE> error. The server
+may enforce a smaller limit, which can be learned with
+L<nbd_get_block_size(3)>.
+
The C<flags> parameter may be C<0> for no flags, or may contain
C<LIBNBD_CMD_FLAG_FUA> meaning that the server should not
return until the data has been committed to permanent storage
@@ -2007,6 +2025,12 @@ The call returns when the command has been acknowledged by the server,
or there is an error. Note this will generally return an error
if L<nbd_can_trim(3)> is false or L<nbd_is_read_only(3)> is true.
+Note that not all servers can support a C<count> of 4GiB or larger.
+The NBD protocol does not yet have a way for a client to learn if
+the server will enforce an even smaller maximum trim size, although
+a future extension may add a constraint visible in
+L<nbd_get_block_size(3)>.
+
The C<flags> parameter may be C<0> for no flags, or may contain
C<LIBNBD_CMD_FLAG_FUA> meaning that the server should not
return until the data has been committed to permanent storage
@@ -2032,6 +2056,12 @@ L<nbd_pread(3)> call. The server can also silently ignore
this command. Note this will generally return an error if
L<nbd_can_cache(3)> is false.
+Note that not all servers can support a C<count> of 4GiB or larger.
+The NBD protocol does not yet have a way for a client to learn if
+the server will enforce an even smaller maximum cache size, although
+a future extension may add a constraint visible in
+L<nbd_get_block_size(3)>.
+
The C<flags> parameter must be C<0> for now (it exists for future NBD
protocol extensions)."
^ strict_call_description;
@@ -2055,6 +2085,13 @@ The call returns when the command has been acknowledged by the server,
or there is an error. Note this will generally return an error if
L<nbd_can_zero(3)> is false or L<nbd_is_read_only(3)> is true.
+Note that not all servers can support a C<count> of 4GiB or larger.
+The NBD protocol does not yet have a way for a client to learn if
+the server will enforce an even smaller maximum zero size, although
+a future extension may add a constraint visible in
+L<nbd_get_block_size(3)>. Also, some servers may permit a larger
+zero request only when the C<LIBNBD_CMD_FLAG_FAST_ZERO> is in use.
+
The C<flags> parameter may be C<0> for no flags, or may contain
C<LIBNBD_CMD_FLAG_FUA> meaning that the server should not
return until the data has been committed to permanent storage
@@ -2088,6 +2125,12 @@ may extend beyond the requested range. If multiple contexts
are supported, the number of blocks and cumulative length
of those blocks need not be identical between contexts.
+Note that not all servers can support a C<count> of 4GiB or larger.
+The NBD protocol does not yet have a way for a client to learn if
+the server will enforce an even smaller maximum block status size,
+although a future extension may add a constraint visible in
+L<nbd_get_block_size(3)>.
+
Depending on which metadata contexts were enabled before
connecting (see L<nbd_add_meta_context(3)>) and which are
supported by the server (see L<nbd_can_meta_context(3)>) this call
--
2.33.1
3 years