summary refs log tree commit diff stats
path: root/results/classifier/108/other/1310
diff options
context:
space:
mode:
Diffstat (limited to 'results/classifier/108/other/1310')
-rw-r--r--results/classifier/108/other/1310205
1 files changed, 205 insertions, 0 deletions
diff --git a/results/classifier/108/other/1310 b/results/classifier/108/other/1310
new file mode 100644
index 000000000..3de5c8e32
--- /dev/null
+++ b/results/classifier/108/other/1310
@@ -0,0 +1,205 @@
+graphic: 0.918
+other: 0.908
+semantic: 0.835
+performance: 0.829
+permissions: 0.821
+debug: 0.809
+vnc: 0.806
+device: 0.759
+KVM: 0.728
+socket: 0.690
+network: 0.673
+boot: 0.668
+PID: 0.645
+files: 0.616
+
+qemu-nbd export img and detect block if is zero with libnbd
+Description of problem:
+In our project,we use qemu-nbd to export a img,and use libnbd to read/write data.if the img is preallocated,we wonder the data block if is zero,we use api nbd_block_status in libnbd to get the block status,but it shows server does not support structured replies: Operation not supported.I know our qemu is too old.so,i want to know how can i know if the block in preallocated is zero or not in nbd client.
+Steps to reproduce:
+1.qemu-nbd -p 8889 -f raw a.img
+
+2.the nbd client use libnbd,code is:
+```c
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <errno.h>
+
+#include <libnbd.h>
+
+static const char *bitmap;
+
+struct data {
+  bool req_one;    /* input: true if req_one was passed to request */
+  int count;       /* input: count of expected remaining calls */
+  bool fail;       /* input: true to return failure */
+  bool seen_base;  /* output: true if base:allocation encountered */
+  bool seen_dirty; /* output: true if qemu:dirty-bitmap encountered */
+};
+
+static int
+cb (void *opaque, const char *metacontext, uint64_t offset,
+    uint32_t *entries, size_t len, int *error)
+{
+  struct data *data = opaque;
+
+  /* libnbd does not actually verify that a server is fully compliant
+   * to the spec; the asserts marked [qemu-nbd] are thus dependent on
+   * the fact that qemu-nbd is compliant.  Furthermore, qemu 5.2 and
+   * 6.0 disagree on whether base:allocation includes the hole bit for
+   * the zeroes at 512k (both answers are compliant); but we care more
+   * that the zeroes show up in the dirty bitmap
+   */
+  assert (offset == 0);
+  assert (!*error || (data->fail && data->count == 1 && *error == EPROTO));
+  assert (data->count-- > 0); /* [qemu-nbd] */
+
+  if (strcmp (metacontext, LIBNBD_CONTEXT_BASE_ALLOCATION) == 0) {
+    assert (!data->seen_base); /* [qemu-nbd] */
+    data->seen_base = true;
+    if (data->req_one)
+      assert (len == 2); /* [qemu-nbd] */
+    else
+      assert ((len & 1) == 0 && len > 2); /* [qemu-nbd] */
+
+    /* Data block offset 0 size 128k */
+    assert (entries[0] == 131072); assert (entries[1] == 0);
+    if (!data->req_one) {
+      if (len == 4) {
+        /* hole|zero offset 128k size 896k */
+        assert (entries[2] == 917504);
+        assert (entries[3] == (LIBNBD_STATE_HOLE|
+                               LIBNBD_STATE_ZERO));
+      }
+      else {
+        assert (len == 8);
+        /* hole|zero offset 128k size 384k */
+        assert (entries[2] == 393216);
+        assert (entries[3] == (LIBNBD_STATE_HOLE|
+                               LIBNBD_STATE_ZERO));
+        /* allocated zero offset 512k size 64k */
+        assert (entries[4] ==  65536);
+        assert (entries[5] == LIBNBD_STATE_ZERO);
+        /* hole|zero offset 576k size 448k */
+        assert (entries[6] == 458752);
+        assert (entries[7] == (LIBNBD_STATE_HOLE|
+                               LIBNBD_STATE_ZERO));
+      }
+    }
+  }
+  else if (strcmp (metacontext, bitmap) == 0) {
+    assert (!data->seen_dirty); /* [qemu-nbd] */
+    data->seen_dirty = true;
+    assert (len == (data->req_one ? 2 : 10)); /* [qemu-nbd] */
+
+    assert (entries[0] ==  65536); assert (entries[1] == 0);
+    if (!data->req_one) {
+      /* dirty block offset 64K size 64K */
+      assert (entries[2] ==  65536); assert (entries[3] == 1);
+      assert (entries[4] == 393216); assert (entries[5] == 0);
+      /* dirty block offset 512K size 64K */
+      assert (entries[6] ==  65536); assert (entries[7] == 1);
+      assert (entries[8] == 458752); assert (entries[9] == 0);
+    }
+  }
+  else {
+    fprintf (stderr, "unexpected context %s\n", metacontext);
+    exit (EXIT_FAILURE);
+  }
+
+  if (data->fail) {
+    /* Something NBD servers can't send */
+    *error = data->count == 1 ? EPROTO : ECONNREFUSED;
+    return -1;
+  }
+  return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+  struct nbd_handle *nbd;
+  int64_t exportsize;
+  struct data data;
+  char c;
+
+  if (argc < 3) {
+    fprintf (stderr, "%s bitmap qemu-nbd [args ...]\n", argv[0]);
+    exit (EXIT_FAILURE);
+  }
+  bitmap = argv[1];
+
+  nbd = nbd_create ();
+  if (nbd == NULL) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  nbd_add_meta_context (nbd, LIBNBD_CONTEXT_BASE_ALLOCATION);
+  nbd_add_meta_context (nbd, bitmap);
+
+  if (nbd_connect_tcp (nbd, argv[2],argv[3]) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  exportsize = nbd_get_size (nbd);
+  if (exportsize == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  data = (struct data) { .count = 2, };
+  if (nbd_block_status (nbd, exportsize, 0,
+                        (nbd_extent_callback) { .callback = cb, .user_data = &data },
+                        0) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+  assert (data.seen_base && data.seen_dirty);
+
+  data = (struct data) { .req_one = true, .count = 2, };
+  if (nbd_block_status (nbd, exportsize, 0,
+                        (nbd_extent_callback) { .callback = cb, .user_data = &data },
+                        LIBNBD_CMD_FLAG_REQ_ONE) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+  assert (data.seen_base && data.seen_dirty);
+
+  /* Trigger a failed callback, to prove connection stays up. */
+  data = (struct data) { .count = 2, .fail = true, };
+  if (nbd_block_status (nbd, exportsize, 0,
+                        (nbd_extent_callback) { .callback = cb, .user_data = &data },
+                        0) != -1) {
+    fprintf (stderr, "unexpected block status success\n");
+    exit (EXIT_FAILURE);
+  }
+  assert (nbd_get_errno () == EPROTO && nbd_aio_is_ready (nbd));
+  assert (data.seen_base && data.seen_dirty);
+
+  if (nbd_pread (nbd, &c, 1, 0, 0) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  if (nbd_shutdown (nbd, 0) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+
+  nbd_close (nbd);
+
+  exit (EXIT_SUCCESS);
+}
+
+```
+3.
+Additional information:
+