Add some small upstream patches since 1.14.0
This commit is contained in:
parent
8a2827c5c4
commit
cccba16e0c
267
0001-dump-Move-ANSI-colours-to-separate-library-under-com.patch
Normal file
267
0001-dump-Move-ANSI-colours-to-separate-library-under-com.patch
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
From 714971885128e7ce657022e8cec665d115186dae Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||||
|
Date: Tue, 2 Aug 2022 09:08:50 +0100
|
||||||
|
Subject: [PATCH 1/3] dump: Move ANSI colours to separate library under
|
||||||
|
common/include
|
||||||
|
|
||||||
|
I've also relicensed the code (which I wrote originally) as BSD, so
|
||||||
|
that we can reuse it in nbdkit.
|
||||||
|
---
|
||||||
|
common/include/Makefile.am | 1 +
|
||||||
|
common/include/ansi-colours.h | 98 +++++++++++++++++++++++++++++++++++
|
||||||
|
dump/dump.c | 68 +++++-------------------
|
||||||
|
3 files changed, 112 insertions(+), 55 deletions(-)
|
||||||
|
create mode 100644 common/include/ansi-colours.h
|
||||||
|
|
||||||
|
diff --git a/common/include/Makefile.am b/common/include/Makefile.am
|
||||||
|
index 4f39c3e8c5..8ff4295e02 100644
|
||||||
|
--- a/common/include/Makefile.am
|
||||||
|
+++ b/common/include/Makefile.am
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
include $(top_srcdir)/subdir-rules.mk
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
+ ansi-colours.h \
|
||||||
|
array-size.h \
|
||||||
|
byte-swapping.h \
|
||||||
|
checked-overflow.h \
|
||||||
|
diff --git a/common/include/ansi-colours.h b/common/include/ansi-colours.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..ebb0b26f6e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/common/include/ansi-colours.h
|
||||||
|
@@ -0,0 +1,98 @@
|
||||||
|
+/* nbdkit
|
||||||
|
+ * Copyright (C) 2022 Red Hat Inc.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions are
|
||||||
|
+ * met:
|
||||||
|
+ *
|
||||||
|
+ * * Redistributions of source code must retain the above copyright
|
||||||
|
+ * notice, this list of conditions and the following disclaimer.
|
||||||
|
+ *
|
||||||
|
+ * * Redistributions in binary form must reproduce the above copyright
|
||||||
|
+ * notice, this list of conditions and the following disclaimer in the
|
||||||
|
+ * documentation and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * * Neither the name of Red Hat nor the names of its contributors may be
|
||||||
|
+ * used to endorse or promote products derived from this software without
|
||||||
|
+ * specific prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
|
||||||
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
|
||||||
|
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
+ * SUCH DAMAGE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef NBDKIT_ANSI_COLOURS_H
|
||||||
|
+#define NBDKIT_ANSI_COLOURS_H
|
||||||
|
+
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+/* For the ansi_* functions, the main program should declare this
|
||||||
|
+ * variable, and initialize it in main() / option parsing. See
|
||||||
|
+ * libnbd.git/dump/dump.c for an example of how to initialize it.
|
||||||
|
+ */
|
||||||
|
+extern bool colour;
|
||||||
|
+
|
||||||
|
+/* Restore the terminal colours to the default.
|
||||||
|
+ *
|
||||||
|
+ * As well as doing this before normal exit, you should also set a
|
||||||
|
+ * signal handler which calls this and fflush(fp). See
|
||||||
|
+ * libnbd.git/dump/dump.c for an example.
|
||||||
|
+ */
|
||||||
|
+static inline void
|
||||||
|
+ansi_restore (FILE *fp)
|
||||||
|
+{
|
||||||
|
+ if (colour)
|
||||||
|
+ fputs ("\033[0m", fp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Set the terminal colour. */
|
||||||
|
+static inline void
|
||||||
|
+ansi_colour (const char *c, FILE *fp)
|
||||||
|
+{
|
||||||
|
+ if (colour)
|
||||||
|
+ fprintf (fp, "\033[%sm", c);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define ANSI_FG_BOLD_BLACK "1;30"
|
||||||
|
+#define ANSI_FG_BLUE "22;34"
|
||||||
|
+#define ANSI_FG_BRIGHT_BLUE "1;34"
|
||||||
|
+#define ANSI_FG_BRIGHT_CYAN "1;36"
|
||||||
|
+#define ANSI_FG_BRIGHT_GREEN "1;32"
|
||||||
|
+#define ANSI_FG_BRIGHT_MAGENTA "1;35"
|
||||||
|
+#define ANSI_FG_BRIGHT_RED "1;31"
|
||||||
|
+#define ANSI_FG_BRIGHT_WHITE "1;37"
|
||||||
|
+#define ANSI_FG_BRIGHT_YELLOW "1;33"
|
||||||
|
+#define ANSI_FG_CYAN "22;36"
|
||||||
|
+#define ANSI_FG_GREEN "22;32"
|
||||||
|
+#define ANSI_FG_GREY "22;90"
|
||||||
|
+#define ANSI_FG_MAGENTA "22;35"
|
||||||
|
+#define ANSI_FG_RED "22;31"
|
||||||
|
+#define ANSI_FG_YELLOW "22;33"
|
||||||
|
+
|
||||||
|
+#define ANSI_BG_BLACK "40"
|
||||||
|
+#define ANSI_BG_LIGHT_GREY "47"
|
||||||
|
+#define ANSI_BG_GREY "100"
|
||||||
|
+
|
||||||
|
+/* Unconditional versions of above (don't depend on global ‘colour’). */
|
||||||
|
+static inline void
|
||||||
|
+ansi_force_restore (FILE *fp)
|
||||||
|
+{
|
||||||
|
+ fputs ("\033[0m", fp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void
|
||||||
|
+ansi_force_colour (const char *c, FILE *fp)
|
||||||
|
+{
|
||||||
|
+ fprintf (fp, "\033[%sm", c);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* NBDKIT_ANSI_COLOURS_H */
|
||||||
|
diff --git a/dump/dump.c b/dump/dump.c
|
||||||
|
index 8bf62f9329..7f0e86e987 100644
|
||||||
|
--- a/dump/dump.c
|
||||||
|
+++ b/dump/dump.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
|
||||||
|
#include <libnbd.h>
|
||||||
|
|
||||||
|
+#include "ansi-colours.h"
|
||||||
|
#include "minmax.h"
|
||||||
|
#include "rounding.h"
|
||||||
|
#include "version.h"
|
||||||
|
@@ -41,7 +42,7 @@ DEFINE_VECTOR_TYPE (uint32_vector, uint32_t)
|
||||||
|
|
||||||
|
static const char *progname;
|
||||||
|
static struct nbd_handle *nbd;
|
||||||
|
-static bool colour;
|
||||||
|
+bool colour;
|
||||||
|
static uint64_t limit = UINT64_MAX; /* --length (unlimited by default) */
|
||||||
|
static int64_t size; /* actual size */
|
||||||
|
static bool can_meta_context; /* did we get extent data? */
|
||||||
|
@@ -244,54 +245,11 @@ do_connect (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Various ANSI colours, suppressed if --no-colour / not tty output. */
|
||||||
|
-static void
|
||||||
|
-ansi_restore (void)
|
||||||
|
-{
|
||||||
|
- if (colour)
|
||||||
|
- fputs ("\033[0m", stdout);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-ansi_blue (void)
|
||||||
|
-{
|
||||||
|
- if (colour)
|
||||||
|
- fputs ("\033[1;34m", stdout);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-ansi_green (void)
|
||||||
|
-{
|
||||||
|
- if (colour)
|
||||||
|
- fputs ("\033[0;32m", stdout);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-ansi_magenta (void)
|
||||||
|
-{
|
||||||
|
- if (colour)
|
||||||
|
- fputs ("\033[1;35m", stdout);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-ansi_red (void)
|
||||||
|
-{
|
||||||
|
- if (colour)
|
||||||
|
- fputs ("\033[1;31m", stdout);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-ansi_grey (void)
|
||||||
|
-{
|
||||||
|
- if (colour)
|
||||||
|
- fputs ("\033[0;90m", stdout);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
catch_signal (int sig)
|
||||||
|
{
|
||||||
|
printf ("\n");
|
||||||
|
- ansi_restore ();
|
||||||
|
+ ansi_restore (stdout);
|
||||||
|
fflush (stdout);
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
@@ -417,21 +375,21 @@ do_dump (void)
|
||||||
|
memcpy (last, &buffer[i], 16); /* Save the current line. */
|
||||||
|
|
||||||
|
/* Print the offset. */
|
||||||
|
- ansi_green ();
|
||||||
|
+ ansi_colour (ANSI_FG_GREEN, stdout);
|
||||||
|
printf ("%010" PRIx64, offset + i);
|
||||||
|
- ansi_grey ();
|
||||||
|
+ ansi_colour (ANSI_FG_GREY, stdout);
|
||||||
|
printf (": ");
|
||||||
|
|
||||||
|
/* Print the hex codes. */
|
||||||
|
for (j = i; j < MIN (i+16, n); ++j) {
|
||||||
|
if (buffer[j])
|
||||||
|
- ansi_blue ();
|
||||||
|
+ ansi_colour (ANSI_FG_BRIGHT_BLUE, stdout);
|
||||||
|
else
|
||||||
|
- ansi_grey ();
|
||||||
|
+ ansi_colour (ANSI_FG_GREY, stdout);
|
||||||
|
printf ("%02x ", buffer[j]);
|
||||||
|
if ((j - i) == 7) printf (" ");
|
||||||
|
}
|
||||||
|
- ansi_grey ();
|
||||||
|
+ ansi_colour (ANSI_FG_GREY, stdout);
|
||||||
|
for (; j < i+16; ++j) {
|
||||||
|
printf (" ");
|
||||||
|
if ((j - i) == 7) printf (" ");
|
||||||
|
@@ -442,23 +400,23 @@ do_dump (void)
|
||||||
|
for (j = i; j < MIN (i+16, n); ++j) {
|
||||||
|
char c = (char) buffer[j];
|
||||||
|
if (isalnum (c)) {
|
||||||
|
- ansi_red ();
|
||||||
|
+ ansi_colour (ANSI_FG_BRIGHT_RED, stdout);
|
||||||
|
printf ("%c", c);
|
||||||
|
}
|
||||||
|
else if (isprint (c)) {
|
||||||
|
- ansi_magenta ();
|
||||||
|
+ ansi_colour (ANSI_FG_BRIGHT_MAGENTA, stdout);
|
||||||
|
printf ("%c", c);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- ansi_grey ();
|
||||||
|
+ ansi_colour (ANSI_FG_GREY, stdout);
|
||||||
|
printf ("%s", dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- ansi_grey ();
|
||||||
|
+ ansi_colour (ANSI_FG_GREY, stdout);
|
||||||
|
for (; j < i+16; ++j)
|
||||||
|
printf (" ");
|
||||||
|
printf ("%s\n", pipe);
|
||||||
|
- ansi_restore ();
|
||||||
|
+ ansi_restore (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += n;
|
||||||
|
--
|
||||||
|
2.37.0.rc2
|
||||||
|
|
400
0002-info-Add-limited-colourized-output.patch
Normal file
400
0002-info-Add-limited-colourized-output.patch
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
From bf4a8911c992291e6943d5e936732c290ea2abb9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||||
|
Date: Tue, 2 Aug 2022 10:38:56 +0100
|
||||||
|
Subject: [PATCH 2/3] info: Add limited colourized output
|
||||||
|
|
||||||
|
For terminal, non-JSON output, colourize some of the output. We can
|
||||||
|
work on making this better later. Use --no-colour (or output to a
|
||||||
|
non-terminal) to disable colours.
|
||||||
|
---
|
||||||
|
info/main.c | 25 ++++++++++++-
|
||||||
|
info/map.c | 95 ++++++++++++++++++++++++++++++++++++++----------
|
||||||
|
info/nbdinfo.pod | 11 ++++++
|
||||||
|
info/show.c | 38 ++++++++++++++-----
|
||||||
|
4 files changed, 138 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/info/main.c b/info/main.c
|
||||||
|
index 870abb4623..a4550e2294 100644
|
||||||
|
--- a/info/main.c
|
||||||
|
+++ b/info/main.c
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/* NBD client library in userspace
|
||||||
|
- * Copyright (C) 2020-2021 Red Hat Inc.
|
||||||
|
+ * Copyright (C) 2020-2022 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
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
|
||||||
|
#include <libnbd.h>
|
||||||
|
|
||||||
|
+#include "ansi-colours.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
#include "nbdinfo.h"
|
||||||
|
@@ -37,6 +38,7 @@
|
||||||
|
const char *progname;
|
||||||
|
struct nbd_handle *nbd;
|
||||||
|
FILE *fp; /* output file descriptor */
|
||||||
|
+bool colour; /* --colour / --no-colour option */
|
||||||
|
bool list_all = false; /* --list option */
|
||||||
|
bool probe_content = false; /* --content / --no-content option */
|
||||||
|
bool json_output = false; /* --json option */
|
||||||
|
@@ -93,6 +95,8 @@ main (int argc, char *argv[])
|
||||||
|
HELP_OPTION = CHAR_MAX + 1,
|
||||||
|
LONG_OPTIONS,
|
||||||
|
SHORT_OPTIONS,
|
||||||
|
+ COLOUR_OPTION,
|
||||||
|
+ NO_COLOUR_OPTION,
|
||||||
|
CONTENT_OPTION,
|
||||||
|
NO_CONTENT_OPTION,
|
||||||
|
JSON_OPTION,
|
||||||
|
@@ -105,6 +109,14 @@ main (int argc, char *argv[])
|
||||||
|
const struct option long_options[] = {
|
||||||
|
{ "help", no_argument, NULL, HELP_OPTION },
|
||||||
|
{ "can", required_argument, NULL, CAN_OPTION },
|
||||||
|
+ { "color", no_argument, NULL, COLOUR_OPTION },
|
||||||
|
+ { "colors", no_argument, NULL, COLOUR_OPTION },
|
||||||
|
+ { "colour", no_argument, NULL, COLOUR_OPTION },
|
||||||
|
+ { "colours", no_argument, NULL, COLOUR_OPTION },
|
||||||
|
+ { "no-color", no_argument, NULL, NO_COLOUR_OPTION },
|
||||||
|
+ { "no-colors", no_argument, NULL, NO_COLOUR_OPTION },
|
||||||
|
+ { "no-colour", no_argument, NULL, NO_COLOUR_OPTION },
|
||||||
|
+ { "no-colours", no_argument, NULL, NO_COLOUR_OPTION },
|
||||||
|
{ "content", no_argument, NULL, CONTENT_OPTION },
|
||||||
|
{ "no-content", no_argument, NULL, NO_CONTENT_OPTION },
|
||||||
|
{ "is", required_argument, NULL, CAN_OPTION },
|
||||||
|
@@ -127,6 +139,7 @@ main (int argc, char *argv[])
|
||||||
|
bool list_okay = true;
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
+ colour = isatty (STDOUT_FILENO);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = getopt_long (argc, argv, short_options, long_options, NULL);
|
||||||
|
@@ -156,6 +169,14 @@ main (int argc, char *argv[])
|
||||||
|
json_output = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case COLOUR_OPTION:
|
||||||
|
+ colour = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case NO_COLOUR_OPTION:
|
||||||
|
+ colour = false;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case CONTENT_OPTION:
|
||||||
|
content_flag = true;
|
||||||
|
break;
|
||||||
|
@@ -288,10 +309,12 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
|
if (!json_output) {
|
||||||
|
if (protocol) {
|
||||||
|
+ ansi_colour (ANSI_FG_MAGENTA, fp);
|
||||||
|
fprintf (fp, "protocol: %s", protocol);
|
||||||
|
if (tls_negotiated >= 0)
|
||||||
|
fprintf (fp, " %s TLS", tls_negotiated ? "with" : "without");
|
||||||
|
fprintf (fp, "\n");
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
diff --git a/info/map.c b/info/map.c
|
||||||
|
index 39c5933bf5..a5aad95522 100644
|
||||||
|
--- a/info/map.c
|
||||||
|
+++ b/info/map.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
|
||||||
|
#include <libnbd.h>
|
||||||
|
|
||||||
|
+#include "ansi-colours.h"
|
||||||
|
#include "minmax.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
@@ -99,7 +100,9 @@ do_map (void)
|
||||||
|
|
||||||
|
/* Callback handling --map. */
|
||||||
|
static void print_one_extent (uint64_t offset, uint64_t len, uint32_t type);
|
||||||
|
-static char *extent_description (const char *metacontext, uint32_t type);
|
||||||
|
+static void extent_description (const char *metacontext, uint32_t type,
|
||||||
|
+ char **descr, bool *free_descr,
|
||||||
|
+ const char **fg, const char **bg);
|
||||||
|
|
||||||
|
static int
|
||||||
|
extent_callback (void *user_data, const char *metacontext,
|
||||||
|
@@ -169,15 +172,25 @@ static void
|
||||||
|
print_one_extent (uint64_t offset, uint64_t len, uint32_t type)
|
||||||
|
{
|
||||||
|
static bool comma = false;
|
||||||
|
- char *descr = extent_description (map, type);
|
||||||
|
+ char *descr;
|
||||||
|
+ bool free_descr;
|
||||||
|
+ const char *fg, *bg;
|
||||||
|
+
|
||||||
|
+ extent_description (map, type, &descr, &free_descr, &fg, &bg);
|
||||||
|
|
||||||
|
if (!json_output) {
|
||||||
|
+ if (fg)
|
||||||
|
+ ansi_colour (fg, fp);
|
||||||
|
+ if (bg)
|
||||||
|
+ ansi_colour (bg, fp);
|
||||||
|
fprintf (fp, "%10" PRIu64 " "
|
||||||
|
"%10" PRIu64 " "
|
||||||
|
"%3" PRIu32,
|
||||||
|
offset, len, type);
|
||||||
|
if (descr)
|
||||||
|
fprintf (fp, " %s", descr);
|
||||||
|
+ if (fg || bg)
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
fprintf (fp, "\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@@ -196,7 +209,8 @@ print_one_extent (uint64_t offset, uint64_t len, uint32_t type)
|
||||||
|
comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- free (descr);
|
||||||
|
+ if (free_descr)
|
||||||
|
+ free (descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --map --totals suboption */
|
||||||
|
@@ -237,14 +251,24 @@ print_totals (uint32_vector *entries, int64_t size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c > 0) {
|
||||||
|
- char *descr = extent_description (map, type);
|
||||||
|
+ char *descr;
|
||||||
|
+ bool free_descr;
|
||||||
|
+ const char *fg, *bg;
|
||||||
|
double percent = 100.0 * c / size;
|
||||||
|
|
||||||
|
+ extent_description (map, type, &descr, &free_descr, &fg, &bg);
|
||||||
|
+
|
||||||
|
if (!json_output) {
|
||||||
|
+ if (fg)
|
||||||
|
+ ansi_colour (fg, fp);
|
||||||
|
+ if (bg)
|
||||||
|
+ ansi_colour (bg, fp);
|
||||||
|
fprintf (fp, "%10" PRIu64 " %5.1f%% %3" PRIu32,
|
||||||
|
c, percent, type);
|
||||||
|
if (descr)
|
||||||
|
fprintf (fp, " %s", descr);
|
||||||
|
+ if (fg || bg)
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
fprintf (fp, "\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@@ -264,7 +288,8 @@ print_totals (uint32_vector *entries, int64_t size)
|
||||||
|
comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- free (descr);
|
||||||
|
+ if (free_descr)
|
||||||
|
+ free (descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_type == (uint64_t)UINT32_MAX + 1)
|
||||||
|
@@ -275,37 +300,67 @@ print_totals (uint32_vector *entries, int64_t size)
|
||||||
|
if (json_output) fprintf (fp, "\n]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
-static char *
|
||||||
|
-extent_description (const char *metacontext, uint32_t type)
|
||||||
|
+static void
|
||||||
|
+extent_description (const char *metacontext, uint32_t type,
|
||||||
|
+ char **descr, bool *free_descr,
|
||||||
|
+ const char **fg, const char **bg)
|
||||||
|
{
|
||||||
|
- char *ret;
|
||||||
|
-
|
||||||
|
if (strcmp (metacontext, "base:allocation") == 0) {
|
||||||
|
switch (type) {
|
||||||
|
- case 0: return strdup ("data");
|
||||||
|
- case 1: return strdup ("hole");
|
||||||
|
- case 2: return strdup ("zero");
|
||||||
|
- case 3: return strdup ("hole,zero");
|
||||||
|
+ case 0:
|
||||||
|
+ *descr = "data"; *free_descr = false;
|
||||||
|
+ *fg = ANSI_FG_BOLD_BLACK; *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
+ case 1:
|
||||||
|
+ *descr = "hole"; *free_descr = false;
|
||||||
|
+ *fg = *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
+ case 2:
|
||||||
|
+ *descr = "zero"; *free_descr = false;
|
||||||
|
+ *fg = *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
+ case 3:
|
||||||
|
+ *descr = "hole,zero"; *free_descr = false;
|
||||||
|
+ *fg = *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strncmp (metacontext, "qemu:dirty-bitmap:", 18) == 0) {
|
||||||
|
switch (type) {
|
||||||
|
- case 0: return strdup ("clean");
|
||||||
|
- case 1: return strdup ("dirty");
|
||||||
|
+ case 0:
|
||||||
|
+ *descr = "clean"; *free_descr = false;
|
||||||
|
+ *fg = ANSI_FG_GREEN; *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
+ case 1:
|
||||||
|
+ *descr = "dirty"; *free_descr = false;
|
||||||
|
+ *fg = ANSI_FG_RED; *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp (metacontext, "qemu:allocation-depth") == 0) {
|
||||||
|
switch (type) {
|
||||||
|
- case 0: return strdup ("absent");
|
||||||
|
- case 1: return strdup ("local");
|
||||||
|
+ case 0:
|
||||||
|
+ *descr = "absent"; *free_descr = false;
|
||||||
|
+ *fg = *bg = NULL;
|
||||||
|
+ return;
|
||||||
|
+ case 1:
|
||||||
|
+ *descr = "local"; *free_descr = false;
|
||||||
|
+ *fg = ANSI_FG_BRIGHT_WHITE; *bg = ANSI_BG_BLACK;
|
||||||
|
+ return;
|
||||||
|
default:
|
||||||
|
- if (asprintf (&ret, "backing depth %u", type) == -1) {
|
||||||
|
+ if (asprintf (descr, "backing depth %u", type) == -1) {
|
||||||
|
perror ("asprintf");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
- return ret;
|
||||||
|
+ *free_descr = true;
|
||||||
|
+ *fg = NULL; *bg = ANSI_BG_LIGHT_GREY;
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- return NULL; /* Don't know - description field will be omitted. */
|
||||||
|
+ /* Don't know - description field will be omitted. */
|
||||||
|
+ *descr = NULL;
|
||||||
|
+ *free_descr = false;
|
||||||
|
+ *fg = NULL;
|
||||||
|
+ *bg = NULL;
|
||||||
|
}
|
||||||
|
diff --git a/info/nbdinfo.pod b/info/nbdinfo.pod
|
||||||
|
index 4733ecd1f7..7dfb9edb60 100644
|
||||||
|
--- a/info/nbdinfo.pod
|
||||||
|
+++ b/info/nbdinfo.pod
|
||||||
|
@@ -330,6 +330,17 @@ L<nbd_can_df(3)>, L<nbd_can_fast_zero(3)>, L<nbd_can_flush(3)>,
|
||||||
|
L<nbd_can_fua(3)>, L<nbd_can_multi_conn(3)>, L<nbd_can_trim(3)>,
|
||||||
|
L<nbd_can_zero(3)>, L<nbd_is_read_only(3)>.
|
||||||
|
|
||||||
|
+=item B<--color>
|
||||||
|
+
|
||||||
|
+=item B<--colour>
|
||||||
|
+
|
||||||
|
+=item B<--no-color>
|
||||||
|
+
|
||||||
|
+=item B<--no-colour>
|
||||||
|
+
|
||||||
|
+Enable or disable ANSI colours in output. By default we use colours
|
||||||
|
+if the output seems to be a terminal, and disable them if not.
|
||||||
|
+
|
||||||
|
=item B<--content>
|
||||||
|
|
||||||
|
=item B<--no-content>
|
||||||
|
diff --git a/info/show.c b/info/show.c
|
||||||
|
index 3a436665bf..140220d8c6 100644
|
||||||
|
--- a/info/show.c
|
||||||
|
+++ b/info/show.c
|
||||||
|
@@ -28,11 +28,13 @@
|
||||||
|
|
||||||
|
#include <libnbd.h>
|
||||||
|
|
||||||
|
+#include "ansi-colours.h"
|
||||||
|
#include "human-size.h"
|
||||||
|
#include "string-vector.h"
|
||||||
|
|
||||||
|
#include "nbdinfo.h"
|
||||||
|
|
||||||
|
+static void show_boolean (const char *name, bool cond);
|
||||||
|
static int collect_context (void *opaque, const char *name);
|
||||||
|
static char *get_content (struct nbd_handle *, int64_t size);
|
||||||
|
|
||||||
|
@@ -119,6 +121,7 @@ show_one_export (struct nbd_handle *nbd, const char *desc,
|
||||||
|
content = get_content (nbd, size);
|
||||||
|
|
||||||
|
if (!json_output) {
|
||||||
|
+ ansi_colour (ANSI_FG_BRIGHT_BLUE, fp);
|
||||||
|
fprintf (fp, "export=");
|
||||||
|
/* Might as well use the JSON function to get an escaped string here ... */
|
||||||
|
print_json_string (export_name);
|
||||||
|
@@ -133,35 +136,38 @@ show_one_export (struct nbd_handle *nbd, const char *desc,
|
||||||
|
fprintf (fp, "\tcontent: %s\n", content);
|
||||||
|
if (uri)
|
||||||
|
fprintf (fp, "\turi: %s\n", uri);
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
+ ansi_colour (ANSI_FG_BLUE, fp);
|
||||||
|
if (show_context) {
|
||||||
|
fprintf (fp, "\tcontexts:\n");
|
||||||
|
for (i = 0; i < contexts.len; ++i)
|
||||||
|
fprintf (fp, "\t\t%s\n", contexts.ptr[i]);
|
||||||
|
}
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
+ ansi_colour (ANSI_FG_MAGENTA, fp);
|
||||||
|
if (is_rotational >= 0)
|
||||||
|
fprintf (fp, "\t%s: %s\n", "is_rotational",
|
||||||
|
is_rotational ? "true" : "false");
|
||||||
|
if (is_read_only >= 0)
|
||||||
|
fprintf (fp, "\t%s: %s\n", "is_read_only",
|
||||||
|
is_read_only ? "true" : "false");
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
if (can_cache >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_cache", can_cache ? "true" : "false");
|
||||||
|
+ show_boolean ("can_cache", can_cache);
|
||||||
|
if (can_df >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_df", can_df ? "true" : "false");
|
||||||
|
+ show_boolean ("can_df", can_df);
|
||||||
|
if (can_fast_zero >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_fast_zero",
|
||||||
|
- can_fast_zero ? "true" : "false");
|
||||||
|
+ show_boolean ("can_fast_zero", can_fast_zero);
|
||||||
|
if (can_flush >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_flush", can_flush ? "true" : "false");
|
||||||
|
+ show_boolean ("can_flush", can_flush);
|
||||||
|
if (can_fua >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_fua", can_fua ? "true" : "false");
|
||||||
|
+ show_boolean ("can_fua", can_fua);
|
||||||
|
if (can_multi_conn >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_multi_conn",
|
||||||
|
- can_multi_conn ? "true" : "false");
|
||||||
|
+ show_boolean ("can_multi_conn", can_multi_conn);
|
||||||
|
if (can_trim >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_trim", can_trim ? "true" : "false");
|
||||||
|
+ show_boolean ("can_trim", can_trim);
|
||||||
|
if (can_zero >= 0)
|
||||||
|
- fprintf (fp, "\t%s: %s\n", "can_zero", can_zero ? "true" : "false");
|
||||||
|
+ show_boolean ("can_zero", can_zero);
|
||||||
|
if (block_minimum > 0)
|
||||||
|
fprintf (fp, "\t%s: %" PRId64 "\n", "block_size_minimum", block_minimum);
|
||||||
|
if (block_preferred > 0)
|
||||||
|
@@ -269,6 +275,18 @@ show_one_export (struct nbd_handle *nbd, const char *desc,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Used for displaying booleans in non-JSON output. */
|
||||||
|
+static void
|
||||||
|
+show_boolean (const char *name, bool cond)
|
||||||
|
+{
|
||||||
|
+ if (cond)
|
||||||
|
+ ansi_colour (ANSI_FG_GREEN, fp);
|
||||||
|
+ else
|
||||||
|
+ ansi_colour (ANSI_FG_RED, fp);
|
||||||
|
+ fprintf (fp, "\t%s: %s\n", name, cond ? "true" : "false");
|
||||||
|
+ ansi_restore (fp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
collect_context (void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.37.0.rc2
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
From 74d5818d42a1e09e6f6f1dccda8254fb8b2c6d57 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||||
|
Date: Tue, 2 Aug 2022 12:38:57 +0100
|
||||||
|
Subject: [PATCH 3/3] info: Improve error message when the export may be
|
||||||
|
unknown to the server
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
$ nbdkit -r file dir=/var/tmp/disks --run 'nbdinfo $uri'
|
||||||
|
nbdkit: file[1]: error: open: : No such file or directory
|
||||||
|
nbdkit: file[1]: error: open: : No such file or directory
|
||||||
|
nbdinfo: nbd_opt_go: server replied with error to opt_go request: No such file or directory for export:
|
||||||
|
|
||||||
|
What happened here is we requested the default export (because the
|
||||||
|
nbdkit-provided $uri points to that). nbdkit-file-plugin doesn't
|
||||||
|
provide a default export so that's an error.
|
||||||
|
|
||||||
|
However the error message is weird and unactionable. We print the
|
||||||
|
default export name, but as that is an empty string we end up printing
|
||||||
|
"for export: ". And we don't tell the user what they can do to
|
||||||
|
recover from this.
|
||||||
|
|
||||||
|
After this commit the message has been improved:
|
||||||
|
|
||||||
|
$ nbdkit -r file dir=/var/tmp/disks --run 'nbdinfo $uri '
|
||||||
|
nbdkit: file[1]: error: open: : No such file or directory
|
||||||
|
nbdkit: file[1]: error: open: : No such file or directory
|
||||||
|
nbdinfo: nbd_opt_go: server replied with error to opt_go request: No such file or directory for the default export
|
||||||
|
nbdinfo: suggestion: to list all exports on the server, use --list
|
||||||
|
|
||||||
|
We now print "default export" if we spot that the default export was
|
||||||
|
requested, and we print an actionable suggestion.
|
||||||
|
---
|
||||||
|
info/show.c | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/info/show.c b/info/show.c
|
||||||
|
index 140220d8c6..df647f3d56 100644
|
||||||
|
--- a/info/show.c
|
||||||
|
+++ b/info/show.c
|
||||||
|
@@ -71,10 +71,20 @@ show_one_export (struct nbd_handle *nbd, const char *desc,
|
||||||
|
fprintf (stderr, "%s: %s", progname, nbd_get_error ());
|
||||||
|
|
||||||
|
char *e = nbd_get_export_name (nbd);
|
||||||
|
- if (e) fprintf (stderr, " for export: %s", e);
|
||||||
|
+ if (e) {
|
||||||
|
+ if (e[0] == '\0')
|
||||||
|
+ fprintf (stderr, " for the default export");
|
||||||
|
+ else
|
||||||
|
+ fprintf (stderr, " for export: %s", e);
|
||||||
|
+ }
|
||||||
|
free (e);
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
|
||||||
|
+ if (!list_all)
|
||||||
|
+ fprintf (stderr, "%s: suggestion: "
|
||||||
|
+ "to list all exports on the server, use --list\n",
|
||||||
|
+ progname);
|
||||||
|
+
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size = nbd_get_size (nbd);
|
||||||
|
--
|
||||||
|
2.37.0.rc2
|
||||||
|
|
10
libnbd.spec
10
libnbd.spec
@ -5,7 +5,7 @@
|
|||||||
%global verify_tarball_signature 1
|
%global verify_tarball_signature 1
|
||||||
|
|
||||||
# If there are patches which touch autotools files, set this to 1.
|
# If there are patches which touch autotools files, set this to 1.
|
||||||
%global patches_touch_autotools %{nil}
|
%global patches_touch_autotools 1
|
||||||
|
|
||||||
# The source directory.
|
# The source directory.
|
||||||
%global source_directory 1.14-stable
|
%global source_directory 1.14-stable
|
||||||
@ -28,6 +28,11 @@ Source2: libguestfs.keyring
|
|||||||
# Maintainer script which helps with handling patches.
|
# Maintainer script which helps with handling patches.
|
||||||
Source3: copy-patches.sh
|
Source3: copy-patches.sh
|
||||||
|
|
||||||
|
# Patches, all upstream after 1.14.0
|
||||||
|
Patch1: 0001-dump-Move-ANSI-colours-to-separate-library-under-com.patch
|
||||||
|
Patch2: 0002-info-Add-limited-colourized-output.patch
|
||||||
|
Patch3: 0003-info-Improve-error-message-when-the-export-may-be-un.patch
|
||||||
|
|
||||||
%if 0%{patches_touch_autotools}
|
%if 0%{patches_touch_autotools}
|
||||||
BuildRequires: autoconf, automake, libtool
|
BuildRequires: autoconf, automake, libtool
|
||||||
%endif
|
%endif
|
||||||
@ -323,6 +328,9 @@ make %{?_smp_mflags} check || {
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Aug 02 2022 Richard W.M. Jones <rjones@redhat.com> - 1.14.0-2
|
||||||
|
- Add some small upstream patches since 1.14.0
|
||||||
|
|
||||||
* Mon Aug 01 2022 Richard W.M. Jones <rjones@redhat.com> - 1.14.0-1
|
* Mon Aug 01 2022 Richard W.M. Jones <rjones@redhat.com> - 1.14.0-1
|
||||||
- New upstream stable version 1.14.0
|
- New upstream stable version 1.14.0
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user