diff --git a/.gitignore b/.gitignore index 58508f5..9768e37 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/libblockdev-2.24.tar.gz +SOURCES/libblockdev-2.28.tar.gz diff --git a/.libblockdev.metadata b/.libblockdev.metadata index babb2b1..996b28a 100644 --- a/.libblockdev.metadata +++ b/.libblockdev.metadata @@ -1 +1 @@ -17e84346cae1ba0fa4cedeada2f8aa10b5000bd3 SOURCES/libblockdev-2.24.tar.gz +d32fce132c75d94ad9c033a636906d63027ffba5 SOURCES/libblockdev-2.28.tar.gz diff --git a/SOURCES/0001-crypto-Fix-GError-overwrite-from-libvolume_key.patch b/SOURCES/0001-crypto-Fix-GError-overwrite-from-libvolume_key.patch new file mode 100644 index 0000000..4a5ee67 --- /dev/null +++ b/SOURCES/0001-crypto-Fix-GError-overwrite-from-libvolume_key.patch @@ -0,0 +1,59 @@ +From 7a0e344d0642f76992c943158621d8ee7e5caea3 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 15 Nov 2022 13:21:25 +0100 +Subject: [PATCH 1/2] crypto: Fix GError overwrite from libvolume_key + +--- + src/plugins/crypto.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c +index 35c38410..9064c8e3 100644 +--- a/src/plugins/crypto.c ++++ b/src/plugins/crypto.c +@@ -2552,13 +2552,14 @@ static gboolean write_escrow_data_file (struct libvk_volume *volume, struct libv + GIOChannel *out_file = NULL; + GIOStatus status = G_IO_STATUS_ERROR; + gsize bytes_written = 0; ++ GError *l_error = NULL; + + packet_data = libvk_volume_create_packet_asymmetric_with_format (volume, &packet_data_size, secret_type, cert, +- ui, LIBVK_PACKET_FORMAT_ASYMMETRIC_WRAP_SECRET_ONLY, error); +- ++ ui, LIBVK_PACKET_FORMAT_ASYMMETRIC_WRAP_SECRET_ONLY, &l_error); + if (!packet_data) { + g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_ESCROW_FAILED, +- "Failed to get escrow data"); ++ "Failed to get escrow data: %s", l_error->message); ++ g_clear_error (&l_error); + libvk_volume_free (volume); + return FALSE; + } +-- +2.38.1 + + +From 25bf34c4c03e37eb3782dfccf459b9a3f795ddb3 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Wed, 16 Nov 2022 10:26:06 +0100 +Subject: [PATCH 2/2] crypto: Fix double free in write_escrow_data_file + +--- + src/plugins/crypto.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c +index 9064c8e3..2086209e 100644 +--- a/src/plugins/crypto.c ++++ b/src/plugins/crypto.c +@@ -2560,7 +2560,6 @@ static gboolean write_escrow_data_file (struct libvk_volume *volume, struct libv + g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_ESCROW_FAILED, + "Failed to get escrow data: %s", l_error->message); + g_clear_error (&l_error); +- libvk_volume_free (volume); + return FALSE; + } + +-- +2.38.1 + diff --git a/SOURCES/0001-exec-Fix-setting-locale-for-util-calls.patch b/SOURCES/0001-exec-Fix-setting-locale-for-util-calls.patch deleted file mode 100644 index 159fa91..0000000 --- a/SOURCES/0001-exec-Fix-setting-locale-for-util-calls.patch +++ /dev/null @@ -1,119 +0,0 @@ -From d9571c2f1cf612ce0d479e428f7b1ae24944d140 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Wed, 10 Jun 2020 17:03:28 +0200 -Subject: [PATCH] exec: Fix setting locale for util calls - -This actually fixes two issue. The _utils_exec_and_report_progress -function didn't set the LC_ALL=C environment variable to make sure -we get output in English. And also we shouldn't use setenv in the -GSpawnChildSetupFunc, it's actually example of what not to do in -g_spawn_async documentation. This fix uses g_environ_setenv and -passes the new environment to the g_spawn call. ---- - src/utils/exec.c | 26 +++++++++++++++++--------- - tests/utils_test.py | 7 +++++++ - 2 files changed, 24 insertions(+), 9 deletions(-) - -diff --git a/src/utils/exec.c b/src/utils/exec.c -index 9293930..37bd960 100644 ---- a/src/utils/exec.c -+++ b/src/utils/exec.c -@@ -140,11 +140,6 @@ static void log_done (guint64 task_id, gint exit_code) { - return; - } - --static void set_c_locale(gpointer user_data __attribute__((unused))) { -- if (setenv ("LC_ALL", "C", 1) != 0) -- g_warning ("Failed to set LC_ALL=C for a child process!"); --} -- - /** - * bd_utils_exec_and_report_error: - * @argv: (array zero-terminated=1): the argv array for the call -@@ -194,6 +189,8 @@ gboolean bd_utils_exec_and_report_status_error (const gchar **argv, const BDExtr - const BDExtraArg **extra_p = NULL; - gint exit_status = 0; - guint i = 0; -+ gchar **old_env = NULL; -+ gchar **new_env = NULL; - - if (extra) { - args_len = g_strv_length ((gchar **) argv); -@@ -219,16 +216,20 @@ gboolean bd_utils_exec_and_report_status_error (const gchar **argv, const BDExtr - args[i] = NULL; - } - -+ old_env = g_get_environ (); -+ new_env = g_environ_setenv (old_env, "LC_ALL", "C", TRUE); -+ - task_id = log_running (args ? args : argv); -- success = g_spawn_sync (NULL, args ? (gchar **) args : (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, -- (GSpawnChildSetupFunc) set_c_locale, NULL, -- &stdout_data, &stderr_data, &exit_status, error); -+ success = g_spawn_sync (NULL, args ? (gchar **) args : (gchar **) argv, new_env, G_SPAWN_SEARCH_PATH, -+ NULL, NULL, &stdout_data, &stderr_data, &exit_status, error); - if (!success) { - /* error is already populated from the call */ -+ g_strfreev (new_env); - g_free (stdout_data); - g_free (stderr_data); - return FALSE; - } -+ g_strfreev (new_env); - - /* g_spawn_sync set the status in the same way waitpid() does, we need - to get the process exit code manually (this is similar to calling -@@ -297,6 +298,8 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - gboolean err_done = FALSE; - GString *stdout_data = g_string_new (NULL); - GString *stderr_data = g_string_new (NULL); -+ gchar **old_env = NULL; -+ gchar **new_env = NULL; - - /* TODO: share this code between functions */ - if (extra) { -@@ -325,7 +328,10 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - - task_id = log_running (args ? args : argv); - -- ret = g_spawn_async_with_pipes (NULL, args ? (gchar**) args : (gchar**) argv, NULL, -+ old_env = g_get_environ (); -+ new_env = g_environ_setenv (old_env, "LC_ALL", "C", TRUE); -+ -+ ret = g_spawn_async_with_pipes (NULL, args ? (gchar**) args : (gchar**) argv, new_env, - G_SPAWN_DEFAULT|G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, &pid, NULL, &out_fd, &err_fd, error); - -@@ -333,9 +339,11 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - /* error is already populated */ - g_string_free (stdout_data, TRUE); - g_string_free (stderr_data, TRUE); -+ g_strfreev (new_env); - g_free (args); - return FALSE; - } -+ g_strfreev (new_env); - - args_str = g_strjoinv (" ", args ? (gchar **) args : (gchar **) argv); - msg = g_strdup_printf ("Started '%s'", args_str); -diff --git a/tests/utils_test.py b/tests/utils_test.py -index 4bec3db..2bec5ed 100644 ---- a/tests/utils_test.py -+++ b/tests/utils_test.py -@@ -170,6 +170,13 @@ class UtilsExecLoggingTest(UtilsTestCase): - # exit code != 0 - self.assertTrue(BlockDev.utils_check_util_version("libblockdev-fake-util-fail", "1.1", "version", "Version:\\s(.*)")) - -+ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) -+ def test_exec_locale(self): -+ """Verify that setting locale for exec functions works as expected""" -+ -+ succ, out = BlockDev.utils_exec_and_capture_output(["locale"]) -+ self.assertTrue(succ) -+ self.assertIn("LC_ALL=C", out) - - class UtilsDevUtilsTestCase(UtilsTestCase): - @tag_test(TestTags.NOSTORAGE, TestTags.CORE) --- -2.26.2 - diff --git a/SOURCES/0002-exec-polling-fixes.patch b/SOURCES/0002-exec-polling-fixes.patch deleted file mode 100644 index 5982f21..0000000 --- a/SOURCES/0002-exec-polling-fixes.patch +++ /dev/null @@ -1,792 +0,0 @@ -From 592820b7a4300cfdc4f85ecd9548f7c2321689fc Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Wed, 16 Sep 2020 17:45:07 +0200 -Subject: [PATCH 1/5] exec: Fix polling for stdout and stderr - -The condition of having both the stdout and the stderr fds ready -may never be satisfied in the case of a full stdout buffer waiting -to be read with no output on stderr yet while both fds being still -open. In such case the old code got stuck in an endless loop and -the spawned process being stuck on writing to stdout/stderr. Let's -read data from any fd once available and only react on EOF/HUP. - -This change also makes use of POSIX poll() instead of g_poll() -as it's more clear what the return values mean - Glib docs are -vague in this regard and one can only guess. ---- - src/utils/exec.c | 32 ++++++++++++++++++-------------- - 1 file changed, 18 insertions(+), 14 deletions(-) - -diff --git a/src/utils/exec.c b/src/utils/exec.c -index 37bd960..ebbcaf2 100644 ---- a/src/utils/exec.c -+++ b/src/utils/exec.c -@@ -22,6 +22,7 @@ - #include "extra_arg.h" - #include - #include -+#include - #include - #include - #include -@@ -293,7 +294,7 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - gint poll_status = 0; - guint i = 0; - guint8 completion = 0; -- GPollFD fds[2] = {ZERO_INIT, ZERO_INIT}; -+ struct pollfd fds[2] = { ZERO_INIT, ZERO_INIT }; - gboolean out_done = FALSE; - gboolean err_done = FALSE; - GString *stdout_data = g_string_new (NULL); -@@ -360,13 +361,16 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - - fds[0].fd = out_fd; - fds[1].fd = err_fd; -- fds[0].events = G_IO_IN | G_IO_HUP | G_IO_ERR; -- fds[1].events = G_IO_IN | G_IO_HUP | G_IO_ERR; -+ fds[0].events = POLLIN | POLLHUP | POLLERR; -+ fds[1].events = POLLIN | POLLHUP | POLLERR; - while (!out_done || !err_done) { -- poll_status = g_poll (fds, 2, -1); -+ poll_status = poll (fds, 2, -1); -+ g_warn_if_fail (poll_status != 0); /* no timeout specified, zero should never be returned */ - if (poll_status < 0) { -+ if (errno == EAGAIN || errno == EINTR) -+ continue; - g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -- "Failed to poll output FDs."); -+ "Failed to poll output FDs: %m"); - bd_utils_report_finished (progress_id, (*error)->message); - g_io_channel_shutdown (out_pipe, FALSE, NULL); - g_io_channel_unref (out_pipe); -@@ -375,12 +379,9 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - g_string_free (stdout_data, TRUE); - g_string_free (stderr_data, TRUE); - return FALSE; -- } else if (poll_status != 2) -- /* both revents fields were not filled yet */ -- continue; -- if (!(fds[0].revents & G_IO_IN)) -- out_done = TRUE; -- while (!out_done) { -+ } -+ -+ while (!out_done && (fds[0].revents & POLLIN)) { - io_status = g_io_channel_read_line (out_pipe, &line, NULL, NULL, error); - if (io_status == G_IO_STATUS_NORMAL) { - if (prog_extract && prog_extract (line, &completion)) -@@ -401,9 +402,10 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - return FALSE; - } - } -- if (!(fds[1].revents & G_IO_IN)) -- err_done = TRUE; -- while (!err_done) { -+ if (fds[0].revents & POLLHUP || fds[0].revents & POLLERR || fds[0].revents & POLLNVAL) -+ out_done = TRUE; -+ -+ while (!err_done && (fds[1].revents & POLLIN)) { - io_status = g_io_channel_read_line (err_pipe, &line, NULL, NULL, error); - if (io_status == G_IO_STATUS_NORMAL) { - g_string_append (stderr_data, line); -@@ -421,6 +423,8 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - return FALSE; - } - } -+ if (fds[1].revents & POLLHUP || fds[1].revents & POLLERR || fds[1].revents & POLLNVAL) -+ err_done = TRUE; - } - - child_ret = waitpid (pid, &status, 0); --- -2.26.2 - - -From 3025deda9ab670a454bfe373166e49f2acd1c151 Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Fri, 25 Sep 2020 18:19:46 +0200 -Subject: [PATCH 2/5] exec: Use non-blocking read and process the buffer - manually - -Waiting for data or a newline character on one fd may create a deadlock -while the other fd is being filled with data, exhausting the pipe buffer. -Setting both stdout and stderr fds non-blocking allows us to get indication -of an empty pipe, continuing with the read cycle over remaining watched fds. - -This also gets rid of GIOChannel as no extended functionality like GSource -notifications were used, degrading GIOChannel in a simple GObject wrapper -over an fd with just a convenience read_line method that we had to get rid of -anyway. Let's use standard POSIX calls and split the read buffer manually -by matching the newline character. NULL bytes should be handled gracefully -however the stack higher up is not ready for that anyway. ---- - src/utils/exec.c | 277 +++++++++++++++++++++++++++-------------------- - 1 file changed, 159 insertions(+), 118 deletions(-) - -diff --git a/src/utils/exec.c b/src/utils/exec.c -index ebbcaf2..317fb55 100644 ---- a/src/utils/exec.c -+++ b/src/utils/exec.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -272,6 +273,87 @@ gboolean bd_utils_exec_and_report_status_error (const gchar **argv, const BDExtr - return TRUE; - } - -+/* buffer size in bytes used to read from stdout and stderr */ -+#define _EXEC_BUF_SIZE 64*1024 -+ -+/* similar to g_strstr_len() yet treats 'null' byte as @needle. */ -+static gchar *bd_strchr_len_null (const gchar *haystack, gssize haystack_len, const gchar needle) { -+ gchar *ret; -+ gchar *ret_null; -+ -+ ret = memchr (haystack, needle, haystack_len); -+ ret_null = memchr (haystack, 0, haystack_len); -+ if (ret && ret_null) -+ return MIN (ret, ret_null); -+ else -+ return MAX (ret, ret_null); -+} -+ -+static gboolean -+_process_fd_event (gint fd, struct pollfd *poll_fd, GString *read_buffer, GString *filtered_buffer, gsize *read_buffer_pos, gboolean *done, -+ guint64 progress_id, guint8 *progress, BDUtilsProgExtract prog_extract, GError **error) { -+ gchar buf[_EXEC_BUF_SIZE] = { 0 }; -+ ssize_t num_read; -+ gchar *line; -+ gchar *newline_pos; -+ int errno_saved; -+ gboolean eof = FALSE; -+ -+ if (! *done && (poll_fd->revents & POLLIN)) { -+ /* read until we get EOF (0) or error (-1), expecting EAGAIN */ -+ while ((num_read = read (fd, buf, _EXEC_BUF_SIZE)) > 0) -+ g_string_append_len (read_buffer, buf, num_read); -+ errno_saved = errno; -+ -+ /* process the fresh data by lines */ -+ if (read_buffer->len > *read_buffer_pos) { -+ gchar *buf_ptr; -+ gsize buf_len; -+ -+ while ((buf_ptr = read_buffer->str + *read_buffer_pos, -+ buf_len = read_buffer->len - *read_buffer_pos, -+ newline_pos = bd_strchr_len_null (buf_ptr, buf_len, '\n'))) { -+ line = g_strndup (buf_ptr, newline_pos - buf_ptr + 1); -+ if (prog_extract && prog_extract (line, progress)) -+ bd_utils_report_progress (progress_id, *progress, NULL); -+ else -+ g_string_append (filtered_buffer, line); -+ g_free (line); -+ *read_buffer_pos = newline_pos - read_buffer->str + 1; -+ } -+ } -+ -+ /* read error */ -+ if (num_read < 0 && errno_saved != EAGAIN && errno_saved != EINTR) { -+ g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -+ "Error reading from pipe: %s", g_strerror (errno_saved)); -+ return FALSE; -+ } -+ -+ /* EOF */ -+ if (num_read == 0) -+ eof = TRUE; -+ } -+ -+ if (poll_fd->revents & POLLHUP || poll_fd->revents & POLLERR || poll_fd->revents & POLLNVAL) -+ eof = TRUE; -+ -+ if (eof) { -+ *done = TRUE; -+ /* process the remaining buffer */ -+ line = read_buffer->str + *read_buffer_pos; -+ /* GString guarantees the buffer is always NULL-terminated. */ -+ if (strlen (line) > 0) { -+ if (prog_extract && prog_extract (line, progress)) -+ bd_utils_report_progress (progress_id, *progress, NULL); -+ else -+ g_string_append (filtered_buffer, line); -+ } -+ } -+ -+ return TRUE; -+} -+ - static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExtraArg **extra, BDUtilsProgExtract prog_extract, gint *proc_status, gchar **stdout, gchar **stderr, GError **error) { - const gchar **args = NULL; - guint args_len = 0; -@@ -283,24 +365,26 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - gchar *msg = NULL; - GPid pid = 0; - gint out_fd = 0; -- GIOChannel *out_pipe = NULL; - gint err_fd = 0; -- GIOChannel *err_pipe = NULL; -- gchar *line = NULL; - gint child_ret = -1; - gint status = 0; - gboolean ret = FALSE; -- GIOStatus io_status = G_IO_STATUS_NORMAL; - gint poll_status = 0; - guint i = 0; - guint8 completion = 0; - struct pollfd fds[2] = { ZERO_INIT, ZERO_INIT }; -+ int flags; - gboolean out_done = FALSE; - gboolean err_done = FALSE; -- GString *stdout_data = g_string_new (NULL); -- GString *stderr_data = g_string_new (NULL); -+ GString *stdout_data; -+ GString *stdout_buffer; -+ GString *stderr_data; -+ GString *stderr_buffer; -+ gsize stdout_buffer_pos = 0; -+ gsize stderr_buffer_pos = 0; - gchar **old_env = NULL; - gchar **new_env = NULL; -+ gboolean success = TRUE; - - /* TODO: share this code between functions */ - if (extra) { -@@ -336,15 +420,13 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - G_SPAWN_DEFAULT|G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, &pid, NULL, &out_fd, &err_fd, error); - -+ g_strfreev (new_env); -+ - if (!ret) { - /* error is already populated */ -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- g_strfreev (new_env); - g_free (args); - return FALSE; - } -- g_strfreev (new_env); - - args_str = g_strjoinv (" ", args ? (gchar **) args : (gchar **) argv); - msg = g_strdup_printf ("Started '%s'", args_str); -@@ -353,18 +435,25 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - g_free (args); - g_free (msg); - -- out_pipe = g_io_channel_unix_new (out_fd); -- err_pipe = g_io_channel_unix_new (err_fd); -+ /* set both fds for non-blocking read */ -+ flags = fcntl (out_fd, F_GETFL, 0); -+ if (fcntl (out_fd, F_SETFL, flags | O_NONBLOCK)) -+ g_warning ("_utils_exec_and_report_progress: Failed to set out_fd non-blocking: %m"); -+ flags = fcntl (err_fd, F_GETFL, 0); -+ if (fcntl (err_fd, F_SETFL, flags | O_NONBLOCK)) -+ g_warning ("_utils_exec_and_report_progress: Failed to set err_fd non-blocking: %m"); - -- g_io_channel_set_encoding (out_pipe, NULL, NULL); -- g_io_channel_set_encoding (err_pipe, NULL, NULL); -+ stdout_data = g_string_new (NULL); -+ stdout_buffer = g_string_new (NULL); -+ stderr_data = g_string_new (NULL); -+ stderr_buffer = g_string_new (NULL); - - fds[0].fd = out_fd; - fds[1].fd = err_fd; - fds[0].events = POLLIN | POLLHUP | POLLERR; - fds[1].events = POLLIN | POLLHUP | POLLERR; -- while (!out_done || !err_done) { -- poll_status = poll (fds, 2, -1); -+ while (! (out_done && err_done)) { -+ poll_status = poll (fds, 2, -1 /* timeout */); - g_warn_if_fail (poll_status != 0); /* no timeout specified, zero should never be returned */ - if (poll_status < 0) { - if (errno == EAGAIN || errno == EINTR) -@@ -372,140 +461,90 @@ static gboolean _utils_exec_and_report_progress (const gchar **argv, const BDExt - g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, - "Failed to poll output FDs: %m"); - bd_utils_report_finished (progress_id, (*error)->message); -- g_io_channel_shutdown (out_pipe, FALSE, NULL); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, NULL); -- g_io_channel_unref (err_pipe); -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- return FALSE; -+ success = FALSE; -+ break; - } - -- while (!out_done && (fds[0].revents & POLLIN)) { -- io_status = g_io_channel_read_line (out_pipe, &line, NULL, NULL, error); -- if (io_status == G_IO_STATUS_NORMAL) { -- if (prog_extract && prog_extract (line, &completion)) -- bd_utils_report_progress (progress_id, completion, NULL); -- else -- g_string_append (stdout_data, line); -- g_free (line); -- } else if (io_status == G_IO_STATUS_EOF) { -- out_done = TRUE; -- } else if (error && (*error)) { -+ if (!out_done) { -+ if (! _process_fd_event (out_fd, &fds[0], stdout_buffer, stdout_data, &stdout_buffer_pos, &out_done, progress_id, &completion, prog_extract, error)) { - bd_utils_report_finished (progress_id, (*error)->message); -- g_io_channel_shutdown (out_pipe, FALSE, NULL); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, NULL); -- g_io_channel_unref (err_pipe); -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- return FALSE; -+ success = FALSE; -+ break; - } - } -- if (fds[0].revents & POLLHUP || fds[0].revents & POLLERR || fds[0].revents & POLLNVAL) -- out_done = TRUE; - -- while (!err_done && (fds[1].revents & POLLIN)) { -- io_status = g_io_channel_read_line (err_pipe, &line, NULL, NULL, error); -- if (io_status == G_IO_STATUS_NORMAL) { -- g_string_append (stderr_data, line); -- g_free (line); -- } else if (io_status == G_IO_STATUS_EOF) { -- err_done = TRUE; -- } else if (error && (*error)) { -+ if (!err_done) { -+ if (! _process_fd_event (err_fd, &fds[1], stderr_buffer, stderr_data, &stderr_buffer_pos, &err_done, progress_id, &completion, prog_extract, error)) { - bd_utils_report_finished (progress_id, (*error)->message); -- g_io_channel_shutdown (out_pipe, FALSE, NULL); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, NULL); -- g_io_channel_unref (err_pipe); -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- return FALSE; -+ success = FALSE; -+ break; - } - } -- if (fds[1].revents & POLLHUP || fds[1].revents & POLLERR || fds[1].revents & POLLNVAL) -- err_done = TRUE; - } - -+ g_string_free (stdout_buffer, TRUE); -+ g_string_free (stderr_buffer, TRUE); -+ close (out_fd); -+ close (err_fd); -+ - child_ret = waitpid (pid, &status, 0); -- *proc_status = WEXITSTATUS(status); -- if (child_ret > 0) { -- if (*proc_status != 0) { -- if (stderr_data->str && (g_strcmp0 ("", stderr_data->str) != 0)) -- msg = stderr_data->str; -- else -- msg = stdout_data->str; -- g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -- "Process reported exit code %d: %s", *proc_status, msg); -- bd_utils_report_finished (progress_id, (*error)->message); -- g_io_channel_shutdown (out_pipe, FALSE, NULL); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, NULL); -- g_io_channel_unref (err_pipe); -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- return FALSE; -- } -- if (WIFSIGNALED(status)) { -- g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -- "Process killed with a signal"); -- bd_utils_report_finished (progress_id, (*error)->message); -- g_io_channel_shutdown (out_pipe, FALSE, NULL); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, NULL); -- g_io_channel_unref (err_pipe); -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- return FALSE; -- } -- } else if (child_ret == -1) { -- if (errno != ECHILD) { -- errno = 0; -- g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -- "Failed to wait for the process"); -- bd_utils_report_finished (progress_id, (*error)->message); -- g_io_channel_shutdown (out_pipe, FALSE, NULL); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, NULL); -- g_io_channel_unref (err_pipe); -- g_string_free (stdout_data, TRUE); -- g_string_free (stderr_data, TRUE); -- return FALSE; -+ *proc_status = WEXITSTATUS (status); -+ if (success) { -+ if (child_ret > 0) { -+ if (*proc_status != 0) { -+ msg = stderr_data->len > 0 ? stderr_data->str : stdout_data->str; -+ g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -+ "Process reported exit code %d: %s", *proc_status, msg); -+ bd_utils_report_finished (progress_id, (*error)->message); -+ success = FALSE; -+ } else if (WIFSIGNALED (status)) { -+ g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -+ "Process killed with a signal"); -+ bd_utils_report_finished (progress_id, (*error)->message); -+ success = FALSE; -+ } -+ } else if (child_ret == -1) { -+ if (errno != ECHILD) { -+ errno = 0; -+ g_set_error (error, BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED, -+ "Failed to wait for the process"); -+ bd_utils_report_finished (progress_id, (*error)->message); -+ success = FALSE; -+ } else { -+ /* no such process (the child exited before we tried to wait for it) */ -+ errno = 0; -+ } - } -- /* no such process (the child exited before we tried to wait for it) */ -- errno = 0; -+ if (success) -+ bd_utils_report_finished (progress_id, "Completed"); - } -- -- bd_utils_report_finished (progress_id, "Completed"); - log_out (task_id, stdout_data->str, stderr_data->str); - log_done (task_id, *proc_status); - -- /* we don't care about the status here */ -- g_io_channel_shutdown (out_pipe, FALSE, error); -- g_io_channel_unref (out_pipe); -- g_io_channel_shutdown (err_pipe, FALSE, error); -- g_io_channel_unref (err_pipe); -- -- if (stdout) -+ if (success && stdout) - *stdout = g_string_free (stdout_data, FALSE); - else - g_string_free (stdout_data, TRUE); -- if (stderr) -+ if (success && stderr) - *stderr = g_string_free (stderr_data, FALSE); - else - g_string_free (stderr_data, TRUE); - -- return TRUE; -+ return success; - } - - /** - * bd_utils_exec_and_report_progress: - * @argv: (array zero-terminated=1): the argv array for the call - * @extra: (allow-none) (array zero-terminated=1): extra arguments -- * @prog_extract: (scope notified): function for extracting progress information -+ * @prog_extract: (scope notified) (nullable): function for extracting progress information - * @proc_status: (out): place to store the process exit status - * @error: (out): place to store error (if any) - * -+ * Note that any NULL bytes read from standard output and standard error -+ * output are treated as separators similar to newlines and @prog_extract -+ * will be called with the respective chunk. -+ * - * Returns: whether the @argv was successfully executed (no error and exit code 0) or not - */ - gboolean bd_utils_exec_and_report_progress (const gchar **argv, const BDExtraArg **extra, BDUtilsProgExtract prog_extract, gint *proc_status, GError **error) { -@@ -519,6 +558,9 @@ gboolean bd_utils_exec_and_report_progress (const gchar **argv, const BDExtraArg - * @output: (out): variable to store output to - * @error: (out): place to store error (if any) - * -+ * Note that any NULL bytes read from standard output and standard error -+ * output will be discarded. -+ * - * Returns: whether the @argv was successfully executed capturing the output or not - */ - gboolean bd_utils_exec_and_capture_output (const gchar **argv, const BDExtraArg **extra, gchar **output, GError **error) { -@@ -549,7 +591,6 @@ gboolean bd_utils_exec_and_capture_output (const gchar **argv, const BDExtraArg - g_free (stderr); - return TRUE; - } -- - } - - /** --- -2.26.2 - - -From f5eb61c91ffc6b0d1fd709076a9579105655ff17 Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Fri, 25 Sep 2020 18:27:02 +0200 -Subject: [PATCH 3/5] exec: Clarify the BDUtilsProgExtract callback - documentation - ---- - src/utils/exec.h | 24 ++++++++++++++++++++++-- - 1 file changed, 22 insertions(+), 2 deletions(-) - -diff --git a/src/utils/exec.h b/src/utils/exec.h -index ad169e4..0e262a2 100644 ---- a/src/utils/exec.h -+++ b/src/utils/exec.h -@@ -31,10 +31,30 @@ typedef void (*BDUtilsProgFunc) (guint64 task_id, BDUtilsProgStatus status, guin - - /** - * BDUtilsProgExtract: -- * @line: line from extract progress from -+ * @line: line to extract progress from - * @completion: (out): percentage of completion - * -- * Returns: whether the line was a progress reporting line or not -+ * Callback function used to process a line captured from spawned command's standard -+ * output and standard error output. Typically used to extract completion percentage -+ * of a long-running job. -+ * -+ * Note that both outputs are read simultaneously with no guarantees of message order -+ * this function is called with. -+ * -+ * The value the @completion points to may contain value previously returned from -+ * this callback or zero when called for the first time. This is useful for extractors -+ * where only some kind of a tick mark is printed out as a progress and previous value -+ * is needed to compute an incremented value. It's important to keep in mind that this -+ * function is only called over lines, i.e. progress reporting printing out tick marks -+ * (e.g. dots) without a newline character might not work properly. -+ * -+ * The @line string usually contains trailing newline character, which may be absent -+ * however in case the spawned command exits without printing one. It's guaranteed -+ * this function is called over remaining buffer no matter what the trailing -+ * character is. -+ * -+ * Returns: whether the line was a progress reporting line and should be excluded -+ * from the collected standard output string or not. - */ - typedef gboolean (*BDUtilsProgExtract) (const gchar *line, guint8 *completion); - --- -2.26.2 - - -From 8a7f0de5f63099a3e8bcaca005c4de04df959113 Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Fri, 25 Sep 2020 18:27:41 +0200 -Subject: [PATCH 4/5] tests: Add bufferbloat exec tests - -This should test pipe buffer exhaustion as well as potential pipe -read starvation while filling the other fd. ---- - tests/utils_test.py | 105 +++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 104 insertions(+), 1 deletion(-) - -diff --git a/tests/utils_test.py b/tests/utils_test.py -index 2bec5ed..ed13611 100644 ---- a/tests/utils_test.py -+++ b/tests/utils_test.py -@@ -1,8 +1,9 @@ - import unittest - import re - import os -+import six - import overrides_hack --from utils import fake_utils, create_sparse_tempfile, create_lio_device, delete_lio_device, run_command, TestTags, tag_test -+from utils import fake_utils, create_sparse_tempfile, create_lio_device, delete_lio_device, run_command, TestTags, tag_test, read_file - - from gi.repository import BlockDev, GLib - -@@ -65,6 +66,9 @@ class UtilsExecLoggingTest(UtilsTestCase): - succ = BlockDev.utils_exec_and_report_error(["true"]) - self.assertTrue(succ) - -+ with six.assertRaisesRegex(self, GLib.GError, r"Process reported exit code 1"): -+ succ = BlockDev.utils_exec_and_report_error(["/bin/false"]) -+ - succ, out = BlockDev.utils_exec_and_capture_output(["echo", "hi"]) - self.assertTrue(succ) - self.assertEqual(out, "hi\n") -@@ -178,6 +182,105 @@ class UtilsExecLoggingTest(UtilsTestCase): - self.assertTrue(succ) - self.assertIn("LC_ALL=C", out) - -+ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) -+ def test_exec_buffer_bloat(self): -+ """Verify that very large output from a command is handled properly""" -+ -+ # easy 64kB of data -+ cnt = 65536 -+ succ, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "for i in {1..%d}; do echo -n .; done" % cnt]) -+ self.assertTrue(succ) -+ self.assertEquals(len(out), cnt) -+ -+ succ, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "for i in {1..%d}; do echo -n .; echo -n \# >&2; done" % cnt]) -+ self.assertTrue(succ) -+ self.assertEquals(len(out), cnt) -+ -+ # now exceed the system pipe buffer size -+ # pipe(7): The maximum size (in bytes) of individual pipes that can be set by users without the CAP_SYS_RESOURCE capability. -+ cnt = int(read_file("/proc/sys/fs/pipe-max-size")) + 100 -+ self.assertGreater(cnt, 0) -+ -+ succ, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "for i in {1..%d}; do echo -n .; done" % cnt]) -+ self.assertTrue(succ) -+ self.assertEquals(len(out), cnt) -+ -+ succ, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "for i in {1..%d}; do echo -n .; echo -n \# >&2; done" % cnt]) -+ self.assertTrue(succ) -+ self.assertEquals(len(out), cnt) -+ -+ # make use of some newlines -+ succ, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "for i in {1..%d}; do echo -n .; if [ $(($i%%500)) -eq 0 ]; then echo ''; fi; done" % cnt]) -+ self.assertTrue(succ) -+ self.assertGreater(len(out), cnt) -+ -+ succ, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "for i in {1..%d}; do echo -n .; echo -n \# >&2; if [ $(($i%%500)) -eq 0 ]; then echo ''; echo '' >&2; fi; done" % cnt]) -+ self.assertTrue(succ) -+ self.assertGreater(len(out), cnt) -+ -+ -+ EXEC_PROGRESS_MSG = "Aloha, I'm the progress line you should match." -+ -+ def my_exec_progress_func_concat(self, line): -+ """Expect an concatenated string""" -+ s = "" -+ for i in range(10): -+ s += self.EXEC_PROGRESS_MSG -+ self.assertEqual(line, s) -+ self.num_matches += 1 -+ return 0 -+ -+ def my_exec_progress_func(self, line): -+ self.assertTrue(re.match(r".*%s.*" % self.EXEC_PROGRESS_MSG, line)) -+ self.num_matches += 1 -+ return 0 -+ -+ def test_exec_buffer_bloat_progress(self): -+ """Verify that progress reporting can handle large output""" -+ -+ # no newlines, should match just a single occurrence on EOF -+ cnt = 10 -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..10}; do echo -n \"%s\"; done" % self.EXEC_PROGRESS_MSG], None, self.my_exec_progress_func_concat) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, 1) -+ -+ # ten matches -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\"; done" % (cnt, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt) -+ -+ # 100k matches -+ cnt = 100000 -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\"; done" % (cnt, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt) -+ -+ # 100k matches on stderr -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt) -+ -+ # 100k matches on stderr and stdout -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\"; echo \"%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt * 2) -+ -+ # stdout and stderr output, non-zero return from the command and very long exception message -+ self.num_matches = 0 -+ with six.assertRaisesRegex(self, GLib.GError, r"Process reported exit code 66"): -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\"; echo \"%s\" >&2; done; exit 66" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertEqual(self.num_matches, cnt * 2) -+ -+ # no progress reporting callback given, tests slightly different code path -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\"; echo \"%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, None) -+ self.assertTrue(status) -+ -+ - class UtilsDevUtilsTestCase(UtilsTestCase): - @tag_test(TestTags.NOSTORAGE, TestTags.CORE) - def test_resolve_device(self): --- -2.26.2 - - -From 7a3fd3d32dd325fb5188bcba74966e414e33c343 Mon Sep 17 00:00:00 2001 -From: Tomas Bzatek -Date: Wed, 30 Sep 2020 14:52:27 +0200 -Subject: [PATCH 5/5] tests: Add null-byte exec tests - -Some commands may print out NULL bytes in the middle of their output, -make sure everything works correctly. ---- - tests/utils_test.py | 48 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/tests/utils_test.py b/tests/utils_test.py -index ed13611..1235be3 100644 ---- a/tests/utils_test.py -+++ b/tests/utils_test.py -@@ -280,6 +280,54 @@ class UtilsExecLoggingTest(UtilsTestCase): - status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo \"%s\"; echo \"%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, None) - self.assertTrue(status) - -+ def test_exec_null_bytes(self): -+ """Verify that null bytes in the output are processed properly""" -+ -+ TEST_DATA = ["First line", "Second line", "Third line"] -+ -+ status, out = BlockDev.utils_exec_and_capture_output(["bash", "-c", "echo -e \"%s\\0%s\\n%s\"" % (TEST_DATA[0], TEST_DATA[1], TEST_DATA[2])]) -+ self.assertTrue(status) -+ self.assertTrue(TEST_DATA[0] in out) -+ self.assertTrue(TEST_DATA[1] in out) -+ self.assertTrue(TEST_DATA[2] in out) -+ self.assertFalse("kuku!" in out) -+ -+ # ten matches -+ cnt = 10 -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo -e \"%s\\0%s\"; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt * 2) -+ -+ # 100k matches -+ cnt = 100000 -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo -e \"%s\\0%s\"; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt * 2) -+ -+ # 100k matches on stderr -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo -e \"%s\\0%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt * 2) -+ -+ # 100k matches on stderr and stdout -+ self.num_matches = 0 -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo -e \"%s\\0%s\"; echo -e \"%s\\0%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertTrue(status) -+ self.assertEqual(self.num_matches, cnt * 4) -+ -+ # stdout and stderr output, non-zero return from the command and very long exception message -+ self.num_matches = 0 -+ with six.assertRaisesRegex(self, GLib.GError, r"Process reported exit code 66"): -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo -e \"%s\\0%s\"; echo -e \"%s\\0%s\" >&2; done; exit 66" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, self.my_exec_progress_func) -+ self.assertEqual(self.num_matches, cnt * 4) -+ -+ # no progress reporting callback given, tests slightly different code path -+ status = BlockDev.utils_exec_and_report_progress(["bash", "-c", "for i in {1..%d}; do echo -e \"%s\\0%s\"; echo -e \"%s\\0%s\" >&2; done" % (cnt, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG, self.EXEC_PROGRESS_MSG)], None, None) -+ self.assertTrue(status) -+ - - class UtilsDevUtilsTestCase(UtilsTestCase): - @tag_test(TestTags.NOSTORAGE, TestTags.CORE) --- -2.26.2 - diff --git a/SOURCES/0003-LVM-thin-metadata-calculation-fix.patch b/SOURCES/0003-LVM-thin-metadata-calculation-fix.patch deleted file mode 100644 index 3eca9ae..0000000 --- a/SOURCES/0003-LVM-thin-metadata-calculation-fix.patch +++ /dev/null @@ -1,914 +0,0 @@ -From 2bb371937c7ef73f26717e57a5eb78cafe90a9f7 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Fri, 20 Sep 2019 09:58:01 +0200 -Subject: [PATCH 1/5] Mark all GIR file constants as guint64 - -See 9676585e65f69ec1c309f45ba139035408d59b8e for more information. ---- - src/lib/plugin_apis/btrfs.api | 2 +- - src/lib/plugin_apis/crypto.api | 2 +- - src/lib/plugin_apis/lvm.api | 20 ++++++++++---------- - src/lib/plugin_apis/mdraid.api | 4 ++-- - 4 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/src/lib/plugin_apis/btrfs.api b/src/lib/plugin_apis/btrfs.api -index b52fb4ce..ef0f6c28 100644 ---- a/src/lib/plugin_apis/btrfs.api -+++ b/src/lib/plugin_apis/btrfs.api -@@ -3,7 +3,7 @@ - #include - - #define BD_BTRFS_MAIN_VOLUME_ID 5 --#define BD_BTRFS_MIN_MEMBER_SIZE (128 MiB) -+#define BD_BTRFS_MIN_MEMBER_SIZE G_GUINT64_CONSTANT (134217728ULL) // 128 MiB - - GQuark bd_btrfs_error_quark (void) { - return g_quark_from_static_string ("g-bd-btrfs-error-quark"); -diff --git a/src/lib/plugin_apis/crypto.api b/src/lib/plugin_apis/crypto.api -index e3d69986..ef0217fe 100644 ---- a/src/lib/plugin_apis/crypto.api -+++ b/src/lib/plugin_apis/crypto.api -@@ -1,7 +1,7 @@ - #include - #include - --#define BD_CRYPTO_LUKS_METADATA_SIZE (2 MiB) -+#define BD_CRYPTO_LUKS_METADATA_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB - - GQuark bd_crypto_error_quark (void) { - return g_quark_from_static_string ("g-bd-crypto-error-quark"); -diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api -index 21c8f74d..ea52263b 100644 ---- a/src/lib/plugin_apis/lvm.api -+++ b/src/lib/plugin_apis/lvm.api -@@ -15,18 +15,18 @@ - #define BD_LVM_MAX_LV_SIZE G_GUINT64_CONSTANT (9223372036854775808ULL) - - --#define BD_LVM_DEFAULT_PE_START (1 MiB) --#define BD_LVM_DEFAULT_PE_SIZE (4 MiB) --#define BD_LVM_MIN_PE_SIZE (1 KiB) --#define BD_LVM_MAX_PE_SIZE (16 GiB) --#define BD_LVM_MIN_THPOOL_MD_SIZE (2 MiB) --#define BD_LVM_MAX_THPOOL_MD_SIZE (16 GiB) --#define BD_LVM_MIN_THPOOL_CHUNK_SIZE (64 KiB) --#define BD_LVM_MAX_THPOOL_CHUNK_SIZE (1 GiB) --#define BD_LVM_DEFAULT_CHUNK_SIZE (64 KiB) -+#define BD_LVM_DEFAULT_PE_START G_GUINT64_CONSTANT (1048576ULL) // 1 MiB -+#define BD_LVM_DEFAULT_PE_SIZE G_GUINT64_CONSTANT (4194304ULL) // 4 MiB -+#define BD_LVM_MIN_PE_SIZE G_GUINT64_CONSTANT (1024ULL) // 1 KiB -+#define BD_LVM_MAX_PE_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB -+#define BD_LVM_MIN_THPOOL_MD_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB -+#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB -+#define BD_LVM_MIN_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB -+#define BD_LVM_MAX_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (1073741824ULL) // 1 GiB -+#define BD_LVM_DEFAULT_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB - - /* according to lvmcache (7) */ --#define BD_LVM_MIN_CACHE_MD_SIZE (8 MiB) -+#define BD_LVM_MIN_CACHE_MD_SIZE (8388608ULL) // 8 MiB - - GQuark bd_lvm_error_quark (void) { - return g_quark_from_static_string ("g-bd-lvm-error-quark"); -diff --git a/src/lib/plugin_apis/mdraid.api b/src/lib/plugin_apis/mdraid.api -index 3bd9eaf2..02ca9530 100644 ---- a/src/lib/plugin_apis/mdraid.api -+++ b/src/lib/plugin_apis/mdraid.api -@@ -7,8 +7,8 @@ - - /* taken from blivet */ - // these defaults were determined empirically --#define BD_MD_SUPERBLOCK_SIZE (2 MiB) --#define BD_MD_CHUNK_SIZE (512 KiB) -+#define BD_MD_SUPERBLOCK_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB -+#define BD_MD_CHUNK_SIZE G_GUINT64_CONSTANT (524288ULL) // 512 KiB - - GQuark bd_md_error_quark (void) { - return g_quark_from_static_string ("g-bd-md-error-quark"); - -From aeedce3bcaa8182c9878cc51d3f85a6c6eb6a01f Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Thu, 3 Dec 2020 14:41:25 +0100 -Subject: [PATCH 2/5] lvm: Set thin metadata limits to match limits LVM uses in - lvcreate - ---- - src/lib/plugin_apis/lvm.api | 4 ++-- - src/plugins/lvm.h | 9 +++++++-- - tests/lvm_dbus_tests.py | 7 ++++--- - tests/lvm_test.py | 7 ++++--- - 4 files changed, 17 insertions(+), 10 deletions(-) - -diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api -index ea52263b..e843c916 100644 ---- a/src/lib/plugin_apis/lvm.api -+++ b/src/lib/plugin_apis/lvm.api -@@ -19,8 +19,8 @@ - #define BD_LVM_DEFAULT_PE_SIZE G_GUINT64_CONSTANT (4194304ULL) // 4 MiB - #define BD_LVM_MIN_PE_SIZE G_GUINT64_CONSTANT (1024ULL) // 1 KiB - #define BD_LVM_MAX_PE_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB --#define BD_LVM_MIN_THPOOL_MD_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB --#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB -+#define BD_LVM_MIN_THPOOL_MD_SIZE G_GUINT64_CONSTANT (4194304ULL) // 4 MiB -+#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (33957085184ULL) // 31.62 GiB - #define BD_LVM_MIN_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB - #define BD_LVM_MAX_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (1073741824ULL) // 1 GiB - #define BD_LVM_DEFAULT_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB -diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h -index 4b970f2e..01c06ca4 100644 ---- a/src/plugins/lvm.h -+++ b/src/plugins/lvm.h -@@ -1,5 +1,6 @@ - #include - #include -+#include - - #ifndef BD_LVM - #define BD_LVM -@@ -21,8 +22,12 @@ - #define USE_DEFAULT_PE_SIZE 0 - #define RESOLVE_PE_SIZE(size) ((size) == USE_DEFAULT_PE_SIZE ? BD_LVM_DEFAULT_PE_SIZE : (size)) - --#define BD_LVM_MIN_THPOOL_MD_SIZE (2 MiB) --#define BD_LVM_MAX_THPOOL_MD_SIZE (16 GiB) -+/* lvm constants for thin pool metadata size are actually half of these -+ but when they calculate the actual metadata size they double the limits -+ so lets just double the limits here too */ -+#define BD_LVM_MIN_THPOOL_MD_SIZE (4 MiB) -+#define BD_LVM_MAX_THPOOL_MD_SIZE (DM_THIN_MAX_METADATA_SIZE KiB) -+ - #define BD_LVM_MIN_THPOOL_CHUNK_SIZE (64 KiB) - #define BD_LVM_MAX_THPOOL_CHUNK_SIZE (1 GiB) - #define BD_LVM_DEFAULT_CHUNK_SIZE (64 KiB) -diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py -index 47402fc3..b517aae9 100644 ---- a/tests/lvm_dbus_tests.py -+++ b/tests/lvm_dbus_tests.py -@@ -160,12 +160,13 @@ def test_get_thpool_meta_size(self): - def test_is_valid_thpool_md_size(self): - """Verify that is_valid_thpool_md_size works as expected""" - -- self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(2 * 1024**2)) -- self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(3 * 1024**2)) -+ self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(4 * 1024**2)) -+ self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(5 * 1024**2)) - self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(16 * 1024**3)) - - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(1 * 1024**2)) -- self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(17 * 1024**3)) -+ self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(3 * 1024**2)) -+ self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(32 * 1024**3)) - - @tag_test(TestTags.NOSTORAGE) - def test_is_valid_thpool_chunk_size(self): -diff --git a/tests/lvm_test.py b/tests/lvm_test.py -index 149cf54a..d0085651 100644 ---- a/tests/lvm_test.py -+++ b/tests/lvm_test.py -@@ -153,12 +153,13 @@ def test_get_thpool_meta_size(self): - def test_is_valid_thpool_md_size(self): - """Verify that is_valid_thpool_md_size works as expected""" - -- self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(2 * 1024**2)) -- self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(3 * 1024**2)) -+ self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(4 * 1024**2)) -+ self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(5 * 1024**2)) - self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(16 * 1024**3)) - - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(1 * 1024**2)) -- self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(17 * 1024**3)) -+ self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(3 * 1024**2)) -+ self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(32 * 1024**3)) - - @tag_test(TestTags.NOSTORAGE) - def test_is_valid_thpool_chunk_size(self): - -From 15fcf1bb62865083a3483fc51f45e11cdc2d7386 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Thu, 3 Dec 2020 14:46:00 +0100 -Subject: [PATCH 3/5] lvm: Do not use thin_metadata_size to recommend thin - metadata size - -thin_metadata_size calculates the metadata size differently and -recommends smaller metadata than lvcreate so we should use the -lvcreate formula instead. - -Resolves: rhbz#1898668 ---- - dist/libblockdev.spec.in | 4 -- - src/lib/plugin_apis/lvm.api | 8 +-- - src/plugins/lvm-dbus.c | 78 ++++++----------------------- - src/plugins/lvm.c | 66 +++++++----------------- - src/python/gi/overrides/BlockDev.py | 6 +++ - tests/library_test.py | 6 +-- - tests/lvm_dbus_tests.py | 20 ++++---- - tests/lvm_test.py | 15 ++---- - tests/utils.py | 2 +- - 9 files changed, 61 insertions(+), 144 deletions(-) - -diff --git a/dist/libblockdev.spec.in b/dist/libblockdev.spec.in -index 7c775174..3e0a53c6 100644 ---- a/dist/libblockdev.spec.in -+++ b/dist/libblockdev.spec.in -@@ -387,8 +387,6 @@ BuildRequires: device-mapper-devel - Summary: The LVM plugin for the libblockdev library - Requires: %{name}-utils%{?_isa} >= 0.11 - Requires: lvm2 --# for thin_metadata_size --Requires: device-mapper-persistent-data - - %description lvm - The libblockdev library plugin (and in the same time a standalone library) -@@ -411,8 +409,6 @@ BuildRequires: device-mapper-devel - Summary: The LVM plugin for the libblockdev library - Requires: %{name}-utils%{?_isa} >= 1.4 - Requires: lvm2-dbusd >= 2.02.156 --# for thin_metadata_size --Requires: device-mapper-persistent-data - - %description lvm-dbus - The libblockdev library plugin (and in the same time a standalone library) -diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api -index e843c916..9f25c1ed 100644 ---- a/src/lib/plugin_apis/lvm.api -+++ b/src/lib/plugin_apis/lvm.api -@@ -704,11 +704,13 @@ guint64 bd_lvm_get_thpool_padding (guint64 size, guint64 pe_size, gboolean inclu - * bd_lvm_get_thpool_meta_size: - * @size: size of the thin pool - * @chunk_size: chunk size of the thin pool or 0 to use the default (%BD_LVM_DEFAULT_CHUNK_SIZE) -- * @n_snapshots: number of snapshots that will be created in the pool -+ * @n_snapshots: ignored - * @error: (out): place to store error (if any) - * -- * Returns: recommended size of the metadata space for the specified pool or 0 -- * in case of error -+ * Note: This function will be changed in 3.0: the @n_snapshots parameter -+ * is currently not used and will be removed. -+ * -+ * Returns: recommended size of the metadata space for the specified pool - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ -diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c -index 9f821a99..24d54426 100644 ---- a/src/plugins/lvm-dbus.c -+++ b/src/plugins/lvm-dbus.c -@@ -20,7 +20,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -248,14 +247,6 @@ static volatile guint avail_features = 0; - static volatile guint avail_module_deps = 0; - static GMutex deps_check_lock; - --#define DEPS_THMS 0 --#define DEPS_THMS_MASK (1 << DEPS_THMS) --#define DEPS_LAST 1 -- --static const UtilDep deps[DEPS_LAST] = { -- {"thin_metadata_size", NULL, NULL, NULL}, --}; -- - #define DBUS_DEPS_LVMDBUSD 0 - #define DBUS_DEPS_LVMDBUSD_MASK (1 << DBUS_DEPS_LVMDBUSD) - #define DBUS_DEPS_LAST 1 -@@ -301,17 +292,6 @@ gboolean bd_lvm_check_deps (void) { - check_ret = check_ret && success; - } - -- for (i=0; i < DEPS_LAST; i++) { -- success = bd_utils_check_util_version (deps[i].name, deps[i].version, -- deps[i].ver_arg, deps[i].ver_regexp, &error); -- if (!success) -- g_warning ("%s", error->message); -- else -- g_atomic_int_or (&avail_deps, 1 << i); -- g_clear_error (&error); -- check_ret = check_ret && success; -- } -- - if (!check_ret) - g_warning("Cannot load the LVM plugin"); - -@@ -386,10 +366,7 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) { - g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_TECH_UNAVAIL, - "Only 'query' supported for thin calculations"); - return FALSE; -- } else if ((mode & BD_LVM_TECH_MODE_QUERY) && -- !check_deps (&avail_deps, DEPS_THMS_MASK, deps, DEPS_LAST, &deps_check_lock, error)) -- return FALSE; -- else -+ } else - return TRUE; - case BD_LVM_TECH_CALCS: - if (mode & ~BD_LVM_TECH_MODE_QUERY) { -@@ -1303,53 +1280,28 @@ guint64 bd_lvm_get_thpool_padding (guint64 size, guint64 pe_size, gboolean inclu - * bd_lvm_get_thpool_meta_size: - * @size: size of the thin pool - * @chunk_size: chunk size of the thin pool or 0 to use the default (%BD_LVM_DEFAULT_CHUNK_SIZE) -- * @n_snapshots: number of snapshots that will be created in the pool -+ * @n_snapshots: ignored - * @error: (out): place to store error (if any) - * -- * Returns: recommended size of the metadata space for the specified pool or 0 -- * in case of error -+ * Note: This function will be changed in 3.0: the @n_snapshots parameter -+ * is currently not used and will be removed. -+ * -+ * Returns: recommended size of the metadata space for the specified pool - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n_snapshots, GError **error) { -- /* ub - output in bytes, n - output just the number */ -- const gchar* args[7] = {"thin_metadata_size", "-ub", "-n", NULL, NULL, NULL, NULL}; -- gchar *output = NULL; -- gboolean success = FALSE; -- guint64 ret = 0; -- -- if (!check_deps (&avail_deps, DEPS_THMS_MASK, deps, DEPS_LAST, &deps_check_lock, error)) -- return 0; -+guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n_snapshots UNUSED, GError **error UNUSED) { -+ guint64 md_size = 0; - -- /* s - total size, b - chunk size, m - number of snapshots */ -- args[3] = g_strdup_printf ("-s%"G_GUINT64_FORMAT, size); -- args[4] = g_strdup_printf ("-b%"G_GUINT64_FORMAT, -- chunk_size != 0 ? chunk_size : (guint64) BD_LVM_DEFAULT_CHUNK_SIZE); -- args[5] = g_strdup_printf ("-m%"G_GUINT64_FORMAT, n_snapshots); -- -- success = bd_utils_exec_and_capture_output (args, NULL, &output, error); -- g_free ((gchar*) args[3]); -- g_free ((gchar*) args[4]); -- g_free ((gchar*) args[5]); -- -- if (!success) { -- /* error is already set */ -- g_free (output); -- return 0; -- } -- -- ret = g_ascii_strtoull (output, NULL, 0); -- if (ret == 0) { -- g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_PARSE, -- "Failed to parse number from thin_metadata_size's output: '%s'", -- output); -- g_free (output); -- return 0; -- } -+ /* based on lvcreate metadata size calculation */ -+ md_size = UINT64_C(64) * size / (chunk_size ? chunk_size : BD_LVM_DEFAULT_CHUNK_SIZE); - -- g_free (output); -+ if (md_size > BD_LVM_MAX_THPOOL_MD_SIZE) -+ md_size = BD_LVM_MAX_THPOOL_MD_SIZE; -+ else if (md_size < BD_LVM_MIN_THPOOL_MD_SIZE) -+ md_size = BD_LVM_MIN_THPOOL_MD_SIZE; - -- return MAX (ret, BD_LVM_MIN_THPOOL_MD_SIZE); -+ return md_size; - } - - /** -diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c -index 6bfaa338..74493feb 100644 ---- a/src/plugins/lvm.c -+++ b/src/plugins/lvm.c -@@ -20,7 +20,6 @@ - #include - #include - #include --#include - #include - #include - -@@ -213,13 +212,10 @@ static GMutex deps_check_lock; - - #define DEPS_LVM 0 - #define DEPS_LVM_MASK (1 << DEPS_LVM) --#define DEPS_THMS 1 --#define DEPS_THMS_MASK (1 << DEPS_THMS) --#define DEPS_LAST 2 -+#define DEPS_LAST 1 - - static const UtilDep deps[DEPS_LAST] = { - {"lvm", LVM_MIN_VERSION, "version", "LVM version:\\s+([\\d\\.]+)"}, -- {"thin_metadata_size", NULL, NULL, NULL}, - }; - - #define FEATURES_VDO 0 -@@ -236,6 +232,8 @@ static const UtilFeatureDep features[FEATURES_LAST] = { - - static const gchar*const module_deps[MODULE_DEPS_LAST] = { "kvdo" }; - -+#define UNUSED __attribute__((unused)) -+ - /** - * bd_lvm_check_deps: - * -@@ -317,10 +315,7 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) { - g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_TECH_UNAVAIL, - "Only 'query' supported for thin calculations"); - return FALSE; -- } else if ((mode & BD_LVM_TECH_MODE_QUERY) && -- !check_deps (&avail_deps, DEPS_THMS_MASK, deps, DEPS_LAST, &deps_check_lock, error)) -- return FALSE; -- else -+ } else - return TRUE; - case BD_LVM_TECH_CALCS: - if (mode & ~BD_LVM_TECH_MODE_QUERY) { -@@ -820,53 +815,28 @@ guint64 bd_lvm_get_thpool_padding (guint64 size, guint64 pe_size, gboolean inclu - * bd_lvm_get_thpool_meta_size: - * @size: size of the thin pool - * @chunk_size: chunk size of the thin pool or 0 to use the default (%BD_LVM_DEFAULT_CHUNK_SIZE) -- * @n_snapshots: number of snapshots that will be created in the pool -+ * @n_snapshots: ignored - * @error: (out): place to store error (if any) - * -- * Returns: recommended size of the metadata space for the specified pool or 0 -- * in case of error -+ * Note: This function will be changed in 3.0: the @n_snapshots parameter -+ * is currently not used and will be removed. -+ * -+ * Returns: recommended size of the metadata space for the specified pool - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n_snapshots, GError **error) { -- /* ub - output in bytes, n - output just the number */ -- const gchar* args[7] = {"thin_metadata_size", "-ub", "-n", NULL, NULL, NULL, NULL}; -- gchar *output = NULL; -- gboolean success = FALSE; -- guint64 ret = 0; -- -- if (!check_deps (&avail_deps, DEPS_THMS_MASK, deps, DEPS_LAST, &deps_check_lock, error)) -- return 0; -+guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n_snapshots UNUSED, GError **error UNUSED) { -+ guint64 md_size = 0; - -- /* s - total size, b - chunk size, m - number of snapshots */ -- args[3] = g_strdup_printf ("-s%"G_GUINT64_FORMAT, size); -- args[4] = g_strdup_printf ("-b%"G_GUINT64_FORMAT, -- chunk_size != 0 ? chunk_size : (guint64) BD_LVM_DEFAULT_CHUNK_SIZE); -- args[5] = g_strdup_printf ("-m%"G_GUINT64_FORMAT, n_snapshots); -+ /* based on lvcreate metadata size calculation */ -+ md_size = UINT64_C(64) * size / (chunk_size ? chunk_size : BD_LVM_DEFAULT_CHUNK_SIZE); - -- success = bd_utils_exec_and_capture_output (args, NULL, &output, error); -- g_free ((gchar*) args[3]); -- g_free ((gchar*) args[4]); -- g_free ((gchar*) args[5]); -- -- if (!success) { -- /* error is already set */ -- g_free (output); -- return 0; -- } -- -- ret = g_ascii_strtoull (output, NULL, 0); -- if (ret == 0) { -- g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_PARSE, -- "Failed to parse number from thin_metadata_size's output: '%s'", -- output); -- g_free (output); -- return 0; -- } -- -- g_free (output); -+ if (md_size > BD_LVM_MAX_THPOOL_MD_SIZE) -+ md_size = BD_LVM_MAX_THPOOL_MD_SIZE; -+ else if (md_size < BD_LVM_MIN_THPOOL_MD_SIZE) -+ md_size = BD_LVM_MIN_THPOOL_MD_SIZE; - -- return MAX (ret, BD_LVM_MIN_THPOOL_MD_SIZE); -+ return md_size; - } - - /** -diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py -index d78bfaab..f768c8bd 100644 ---- a/src/python/gi/overrides/BlockDev.py -+++ b/src/python/gi/overrides/BlockDev.py -@@ -462,6 +462,12 @@ def lvm_get_thpool_padding(size, pe_size=0, included=False): - return _lvm_get_thpool_padding(size, pe_size, included) - __all__.append("lvm_get_thpool_padding") - -+_lvm_get_thpool_meta_size = BlockDev.lvm_get_thpool_meta_size -+@override(BlockDev.lvm_get_thpool_meta_size) -+def lvm_get_thpool_meta_size(size, chunk_size=0, n_snapshots=0): -+ return _lvm_get_thpool_meta_size(size, chunk_size, n_snapshots) -+__all__.append("lvm_get_thpool_meta_size") -+ - _lvm_pvcreate = BlockDev.lvm_pvcreate - @override(BlockDev.lvm_pvcreate) - def lvm_pvcreate(device, data_alignment=0, metadata_size=0, extra=None, **kwargs): -diff --git a/tests/library_test.py b/tests/library_test.py -index e8bb175a..08e44fdc 100644 ---- a/tests/library_test.py -+++ b/tests/library_test.py -@@ -349,8 +349,7 @@ def test_try_reinit(self): - - # try reinitializing with only some utilities being available and thus - # only some plugins able to load -- with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "lvm", -- "thin_metadata_size", "swaplabel"]): -+ with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "lvm", "swaplabel"]): - succ, loaded = BlockDev.try_reinit(self.requested_plugins, True, None) - self.assertFalse(succ) - for plug_name in ("swap", "lvm", "crypto"): -@@ -361,8 +360,7 @@ def test_try_reinit(self): - - # now the same with a subset of plugins requested - plugins = BlockDev.plugin_specs_from_names(["lvm", "swap", "crypto"]) -- with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "lvm", -- "thin_metadata_size", "swaplabel"]): -+ with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "lvm","swaplabel"]): - succ, loaded = BlockDev.try_reinit(plugins, True, None) - self.assertTrue(succ) - self.assertEqual(set(loaded), set(["swap", "lvm", "crypto"])) -diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py -index b517aae9..c06a480c 100644 ---- a/tests/lvm_dbus_tests.py -+++ b/tests/lvm_dbus_tests.py -@@ -141,21 +141,19 @@ def test_get_thpool_padding(self): - def test_get_thpool_meta_size(self): - """Verify that getting recommended thin pool metadata size works as expected""" - -- # no idea how thin_metadata_size works, but let's at least check that -- # the function works and returns what thin_metadata_size says -- out1 = subprocess.check_output(["thin_metadata_size", "-ub", "-n", "-b64k", "-s1t", "-m100"]) -- self.assertEqual(int(out1), BlockDev.lvm_get_thpool_meta_size (1 * 1024**4, 64 * 1024, 100)) -+ # metadata size is calculated as 64 * pool_size / chunk_size -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(1 * 1024**4, 64 * 1024), 1 * 1024**3) - -- out2 = subprocess.check_output(["thin_metadata_size", "-ub", "-n", "-b128k", "-s1t", "-m100"]) -- self.assertEqual(int(out2), BlockDev.lvm_get_thpool_meta_size (1 * 1024**4, 128 * 1024, 100)) -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(1 * 1024**4, 128 * 1024), 512 * 1024**2) - -- # twice the chunk_size -> roughly half the metadata needed -- self.assertAlmostEqual(float(out1) / float(out2), 2, places=2) -- -- # unless thin_metadata_size gives a value that is not valid (too small) -- self.assertEqual(BlockDev.lvm_get_thpool_meta_size (100 * 1024**2, 128 * 1024, 100), -+ # lower limit is 4 MiB -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(100 * 1024**2, 128 * 1024), - BlockDev.LVM_MIN_THPOOL_MD_SIZE) - -+ # upper limit is 31.62 GiB -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(100 * 1024**4, 64 * 1024), -+ BlockDev.LVM_MAX_THPOOL_MD_SIZE) -+ - @tag_test(TestTags.NOSTORAGE) - def test_is_valid_thpool_md_size(self): - """Verify that is_valid_thpool_md_size works as expected""" -diff --git a/tests/lvm_test.py b/tests/lvm_test.py -index d0085651..b84adece 100644 ---- a/tests/lvm_test.py -+++ b/tests/lvm_test.py -@@ -134,19 +134,14 @@ def test_get_thpool_padding(self): - def test_get_thpool_meta_size(self): - """Verify that getting recommended thin pool metadata size works as expected""" - -- # no idea how thin_metadata_size works, but let's at least check that -- # the function works and returns what thin_metadata_size says -- out1 = subprocess.check_output(["thin_metadata_size", "-ub", "-n", "-b64k", "-s1t", "-m100"]) -- self.assertEqual(int(out1), BlockDev.lvm_get_thpool_meta_size (1 * 1024**4, 64 * 1024, 100)) - -- out2 = subprocess.check_output(["thin_metadata_size", "-ub", "-n", "-b128k", "-s1t", "-m100"]) -- self.assertEqual(int(out2), BlockDev.lvm_get_thpool_meta_size (1 * 1024**4, 128 * 1024, 100)) -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(1 * 1024**4, 64 * 1024), -+ 1 * 1024**3) - -- # twice the chunk_size -> roughly half the metadata needed -- self.assertAlmostEqual(float(out1) / float(out2), 2, places=2) -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(1 * 1024**4, 128 * 1024), -+ 512 * 1024**2) - -- # unless thin_metadata_size gives a value that is not valid (too small) -- self.assertEqual(BlockDev.lvm_get_thpool_meta_size (100 * 1024**2, 128 * 1024, 100), -+ self.assertEqual(BlockDev.lvm_get_thpool_meta_size(100 * 1024**2, 128 * 1024), - BlockDev.LVM_MIN_THPOOL_MD_SIZE) - - @tag_test(TestTags.NOSTORAGE) -diff --git a/tests/utils.py b/tests/utils.py -index 182eda6a..584fde5c 100644 ---- a/tests/utils.py -+++ b/tests/utils.py -@@ -70,7 +70,7 @@ def fake_utils(path="."): - finally: - os.environ["PATH"] = old_path - --ALL_UTILS = {"lvm", "thin_metadata_size", "btrfs", "mkswap", "swaplabel", "multipath", "mpathconf", "dmsetup", "mdadm", "make-bcache", "sgdisk", "sfdisk"} -+ALL_UTILS = {"lvm", "btrfs", "mkswap", "swaplabel", "multipath", "mpathconf", "dmsetup", "mdadm", "make-bcache", "sgdisk", "sfdisk"} - - @contextmanager - def fake_path(path=None, keep_utils=None, all_but=None): - -From 27961a3fcb205ea51f40668d68765dd8d388777b Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Thu, 3 Dec 2020 14:48:08 +0100 -Subject: [PATCH 4/5] lvm: Use the UNUSED macro instead of - __attribute__((unused)) - -for unused attributes. It makes the function definition a little -bit more readable. ---- - src/plugins/lvm-dbus.c | 24 ++++++++++++------------ - src/plugins/lvm.c | 20 ++++++++++---------- - 2 files changed, 22 insertions(+), 22 deletions(-) - -diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c -index 24d54426..b7b4480e 100644 ---- a/src/plugins/lvm-dbus.c -+++ b/src/plugins/lvm-dbus.c -@@ -959,7 +959,7 @@ static BDLVMPVdata* get_pv_data_from_props (GVariant *props, GError **error) { - return data; - } - --static BDLVMVGdata* get_vg_data_from_props (GVariant *props, GError **error __attribute__((unused))) { -+static BDLVMVGdata* get_vg_data_from_props (GVariant *props, GError **error UNUSED) { - BDLVMVGdata *data = g_new0 (BDLVMVGdata, 1); - GVariantDict dict; - -@@ -1061,7 +1061,7 @@ static BDLVMLVdata* get_lv_data_from_props (GVariant *props, GError **error) { - return data; - } - --static BDLVMVDOPooldata* get_vdo_data_from_props (GVariant *props, GError **error __attribute__((unused))) { -+static BDLVMVDOPooldata* get_vdo_data_from_props (GVariant *props, GError **error UNUSED) { - BDLVMVDOPooldata *data = g_new0 (BDLVMVDOPooldata, 1); - GVariantDict dict; - gchar *value = NULL; -@@ -1165,7 +1165,7 @@ static GVariant* create_size_str_param (guint64 size, const gchar *unit) { - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error __attribute__((unused))) { -+gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error UNUSED) { - return (((size % 2) == 0) && (size >= (BD_LVM_MIN_PE_SIZE)) && (size <= (BD_LVM_MAX_PE_SIZE))); - } - -@@ -1177,7 +1177,7 @@ gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error __attribute__ - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --guint64 *bd_lvm_get_supported_pe_sizes (GError **error __attribute__((unused))) { -+guint64 *bd_lvm_get_supported_pe_sizes (GError **error UNUSED) { - guint8 i; - guint64 val = BD_LVM_MIN_PE_SIZE; - guint8 num_items = ((guint8) round (log2 ((double) BD_LVM_MAX_PE_SIZE))) - ((guint8) round (log2 ((double) BD_LVM_MIN_PE_SIZE))) + 2; -@@ -1199,7 +1199,7 @@ guint64 *bd_lvm_get_supported_pe_sizes (GError **error __attribute__((unused))) - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_get_max_lv_size (GError **error __attribute__((unused))) { -+guint64 bd_lvm_get_max_lv_size (GError **error UNUSED) { - return BD_LVM_MAX_LV_SIZE; - } - -@@ -1219,7 +1219,7 @@ guint64 bd_lvm_get_max_lv_size (GError **error __attribute__((unused))) { - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_round_size_to_pe (guint64 size, guint64 pe_size, gboolean roundup, GError **error __attribute__((unused))) { -+guint64 bd_lvm_round_size_to_pe (guint64 size, guint64 pe_size, gboolean roundup, GError **error UNUSED) { - pe_size = RESOLVE_PE_SIZE(pe_size); - guint64 delta = size % pe_size; - if (delta == 0) -@@ -1313,7 +1313,7 @@ guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ --gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error __attribute__((unused))) { -+gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error UNUSED) { - return ((BD_LVM_MIN_THPOOL_MD_SIZE <= size) && (size <= BD_LVM_MAX_THPOOL_MD_SIZE)); - } - -@@ -1327,7 +1327,7 @@ gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error __attribut - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ --gboolean bd_lvm_is_valid_thpool_chunk_size (guint64 size, gboolean discard, GError **error __attribute__((unused))) { -+gboolean bd_lvm_is_valid_thpool_chunk_size (guint64 size, gboolean discard, GError **error UNUSED) { - gdouble size_log2 = 0.0; - - if ((size < BD_LVM_MIN_THPOOL_CHUNK_SIZE) || (size > BD_LVM_MAX_THPOOL_CHUNK_SIZE)) -@@ -2616,7 +2616,7 @@ gboolean bd_lvm_thsnapshotcreate (const gchar *vg_name, const gchar *origin_name - * - * Tech category: %BD_LVM_TECH_GLOB_CONF no mode (it is ignored) - */ --gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error __attribute__((unused))) { -+gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error UNUSED) { - /* XXX: the error attribute will likely be used in the future when - some validation comes into the game */ - -@@ -2641,7 +2641,7 @@ gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error __att - * - * Tech category: %BD_LVM_TECH_GLOB_CONF no mode (it is ignored) - */ --gchar* bd_lvm_get_global_config (GError **error __attribute__((unused))) { -+gchar* bd_lvm_get_global_config (GError **error UNUSED) { - gchar *ret = NULL; - - g_mutex_lock (&global_config_lock); -@@ -2660,7 +2660,7 @@ gchar* bd_lvm_get_global_config (GError **error __attribute__((unused))) { - * - * Tech category: %BD_LVM_TECH_CACHE_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error __attribute__((unused))) { -+guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error UNUSED) { - return MAX ((guint64) cache_size / 1000, BD_LVM_MIN_CACHE_MD_SIZE); - } - -@@ -2670,7 +2670,7 @@ guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error __a - * - * Get LV type string from flags. - */ --static const gchar* get_lv_type_from_flags (BDLVMCachePoolFlags flags, gboolean meta, GError **error __attribute__((unused))) { -+static const gchar* get_lv_type_from_flags (BDLVMCachePoolFlags flags, gboolean meta, GError **error UNUSED) { - if (!meta) { - if (flags & BD_LVM_CACHE_POOL_STRIPED) - return "striped"; -diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c -index 74493feb..2be1dbdb 100644 ---- a/src/plugins/lvm.c -+++ b/src/plugins/lvm.c -@@ -700,7 +700,7 @@ static BDLVMVDOPooldata* get_vdo_data_from_table (GHashTable *table, gboolean fr - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error __attribute__((unused))) { -+gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error UNUSED) { - return (((size % 2) == 0) && (size >= (BD_LVM_MIN_PE_SIZE)) && (size <= (BD_LVM_MAX_PE_SIZE))); - } - -@@ -712,7 +712,7 @@ gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error __attribute__ - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --guint64 *bd_lvm_get_supported_pe_sizes (GError **error __attribute__((unused))) { -+guint64 *bd_lvm_get_supported_pe_sizes (GError **error UNUSED) { - guint8 i; - guint64 val = BD_LVM_MIN_PE_SIZE; - guint8 num_items = ((guint8) round (log2 ((double) BD_LVM_MAX_PE_SIZE))) - ((guint8) round (log2 ((double) BD_LVM_MIN_PE_SIZE))) + 2; -@@ -734,7 +734,7 @@ guint64 *bd_lvm_get_supported_pe_sizes (GError **error __attribute__((unused))) - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_get_max_lv_size (GError **error __attribute__((unused))) { -+guint64 bd_lvm_get_max_lv_size (GError **error UNUSED) { - return BD_LVM_MAX_LV_SIZE; - } - -@@ -754,7 +754,7 @@ guint64 bd_lvm_get_max_lv_size (GError **error __attribute__((unused))) { - * - * Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_round_size_to_pe (guint64 size, guint64 pe_size, gboolean roundup, GError **error __attribute__((unused))) { -+guint64 bd_lvm_round_size_to_pe (guint64 size, guint64 pe_size, gboolean roundup, GError **error UNUSED) { - pe_size = RESOLVE_PE_SIZE(pe_size); - guint64 delta = size % pe_size; - if (delta == 0) -@@ -848,7 +848,7 @@ guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ --gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error __attribute__((unused))) { -+gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error UNUSED) { - return ((BD_LVM_MIN_THPOOL_MD_SIZE <= size) && (size <= BD_LVM_MAX_THPOOL_MD_SIZE)); - } - -@@ -862,7 +862,7 @@ gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error __attribut - * - * Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored) - */ --gboolean bd_lvm_is_valid_thpool_chunk_size (guint64 size, gboolean discard, GError **error __attribute__((unused))) { -+gboolean bd_lvm_is_valid_thpool_chunk_size (guint64 size, gboolean discard, GError **error UNUSED) { - gdouble size_log2 = 0.0; - - if ((size < BD_LVM_MIN_THPOOL_CHUNK_SIZE) || (size > BD_LVM_MAX_THPOOL_CHUNK_SIZE)) -@@ -1983,7 +1983,7 @@ gboolean bd_lvm_thsnapshotcreate (const gchar *vg_name, const gchar *origin_name - * - * Tech category: %BD_LVM_TECH_GLOB_CONF no mode (it is ignored) - */ --gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error __attribute__((unused))) { -+gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error UNUSED) { - /* XXX: the error attribute will likely be used in the future when - some validation comes into the game */ - -@@ -2008,7 +2008,7 @@ gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error __att - * - * Tech category: %BD_LVM_TECH_GLOB_CONF no mode (it is ignored) - */ --gchar* bd_lvm_get_global_config (GError **error __attribute__((unused))) { -+gchar* bd_lvm_get_global_config (GError **error UNUSED) { - gchar *ret = NULL; - - g_mutex_lock (&global_config_lock); -@@ -2027,7 +2027,7 @@ gchar* bd_lvm_get_global_config (GError **error __attribute__((unused))) { - * - * Tech category: %BD_LVM_TECH_CACHE_CALCS no mode (it is ignored) - */ --guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error __attribute__((unused))) { -+guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error UNUSED) { - return MAX ((guint64) cache_size / 1000, BD_LVM_MIN_CACHE_MD_SIZE); - } - -@@ -2037,7 +2037,7 @@ guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error __a - * - * Get LV type string from flags. - */ --static const gchar* get_lv_type_from_flags (BDLVMCachePoolFlags flags, gboolean meta, GError **error __attribute__((unused))) { -+static const gchar* get_lv_type_from_flags (BDLVMCachePoolFlags flags, gboolean meta, GError **error UNUSED) { - if (!meta) { - if (flags & BD_LVM_CACHE_POOL_STRIPED) - return "striped"; - -From f106e775d3c73e5f97512dd109627e00539b703a Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Tue, 15 Dec 2020 14:53:13 +0100 -Subject: [PATCH 5/5] Fix max size limit for LVM thinpool metadata - -DM_THIN_MAX_METADATA_SIZE is in 512 sectors, not in KiB so the -upper limit is 15.81 GiB not 31.62 GiB ---- - src/lib/plugin_apis/lvm.api | 2 +- - src/plugins/lvm.h | 10 ++++++---- - tests/lvm_dbus_tests.py | 3 ++- - tests/lvm_test.py | 3 ++- - 4 files changed, 11 insertions(+), 7 deletions(-) - -diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api -index 9f25c1ed..563c1041 100644 ---- a/src/lib/plugin_apis/lvm.api -+++ b/src/lib/plugin_apis/lvm.api -@@ -20,7 +20,7 @@ - #define BD_LVM_MIN_PE_SIZE G_GUINT64_CONSTANT (1024ULL) // 1 KiB - #define BD_LVM_MAX_PE_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB - #define BD_LVM_MIN_THPOOL_MD_SIZE G_GUINT64_CONSTANT (4194304ULL) // 4 MiB --#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (33957085184ULL) // 31.62 GiB -+#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (16978542592ULL) // 15.81 GiB - #define BD_LVM_MIN_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB - #define BD_LVM_MAX_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (1073741824ULL) // 1 GiB - #define BD_LVM_DEFAULT_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB -diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h -index 01c06ca4..2162d769 100644 ---- a/src/plugins/lvm.h -+++ b/src/plugins/lvm.h -@@ -22,11 +22,13 @@ - #define USE_DEFAULT_PE_SIZE 0 - #define RESOLVE_PE_SIZE(size) ((size) == USE_DEFAULT_PE_SIZE ? BD_LVM_DEFAULT_PE_SIZE : (size)) - --/* lvm constants for thin pool metadata size are actually half of these -- but when they calculate the actual metadata size they double the limits -- so lets just double the limits here too */ -+/* lvm constant for thin pool metadata size is actually half of this -+ but when they calculate the actual metadata size they double the limit -+ so lets just double the limit here too */ - #define BD_LVM_MIN_THPOOL_MD_SIZE (4 MiB) --#define BD_LVM_MAX_THPOOL_MD_SIZE (DM_THIN_MAX_METADATA_SIZE KiB) -+ -+/* DM_THIN_MAX_METADATA_SIZE is in 512 sectors */ -+#define BD_LVM_MAX_THPOOL_MD_SIZE (DM_THIN_MAX_METADATA_SIZE * 512) - - #define BD_LVM_MIN_THPOOL_CHUNK_SIZE (64 KiB) - #define BD_LVM_MAX_THPOOL_CHUNK_SIZE (1 GiB) -diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py -index c06a480c..8f2bb95d 100644 ---- a/tests/lvm_dbus_tests.py -+++ b/tests/lvm_dbus_tests.py -@@ -160,10 +160,11 @@ def test_is_valid_thpool_md_size(self): - - self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(4 * 1024**2)) - self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(5 * 1024**2)) -- self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(16 * 1024**3)) -+ self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(15 * 1024**3)) - - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(1 * 1024**2)) - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(3 * 1024**2)) -+ self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(16 * 1024**3)) - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(32 * 1024**3)) - - @tag_test(TestTags.NOSTORAGE) -diff --git a/tests/lvm_test.py b/tests/lvm_test.py -index b84adece..6f80a3ba 100644 ---- a/tests/lvm_test.py -+++ b/tests/lvm_test.py -@@ -150,10 +150,11 @@ def test_is_valid_thpool_md_size(self): - - self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(4 * 1024**2)) - self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(5 * 1024**2)) -- self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(16 * 1024**3)) -+ self.assertTrue(BlockDev.lvm_is_valid_thpool_md_size(15 * 1024**3)) - - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(1 * 1024**2)) - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(3 * 1024**2)) -+ self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(16 * 1024**3)) - self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(32 * 1024**3)) - - @tag_test(TestTags.NOSTORAGE) diff --git a/SOURCES/0004-Fix-default-key-size-for-non-XTS-ciphers.patch b/SOURCES/0004-Fix-default-key-size-for-non-XTS-ciphers.patch deleted file mode 100644 index 6292ac7..0000000 --- a/SOURCES/0004-Fix-default-key-size-for-non-XTS-ciphers.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 5d29bc014a33d9bdc1c5fb4b8add2f38850f46a8 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Wed, 24 Feb 2021 14:44:03 +0100 -Subject: [PATCH] crypto: Fix default key size for non XTS ciphers - -512 bits should be default only for AES-XTS which needs two keys, -default for other modes must be 256 bits. - -resolves: rhbz#1931847 ---- - src/plugins/crypto.c | 11 +++++++++-- - src/plugins/crypto.h | 2 +- - tests/crypto_test.py | 36 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 46 insertions(+), 3 deletions(-) - -diff --git a/src/plugins/crypto.c b/src/plugins/crypto.c -index f4a2e8f0..1e7043fa 100644 ---- a/src/plugins/crypto.c -+++ b/src/plugins/crypto.c -@@ -774,8 +774,15 @@ static gboolean luks_format (const gchar *device, const gchar *cipher, guint64 k - return FALSE; - } - -- /* resolve requested/default key_size (should be in bytes) */ -- key_size = (key_size != 0) ? (key_size / 8) : (DEFAULT_LUKS_KEYSIZE_BITS / 8); -+ if (key_size == 0) { -+ if (g_str_has_prefix (cipher_specs[1], "xts-")) -+ key_size = DEFAULT_LUKS_KEYSIZE_BITS * 2; -+ else -+ key_size = DEFAULT_LUKS_KEYSIZE_BITS; -+ } -+ -+ /* key_size should be in bytes */ -+ key_size = key_size / 8; - - /* wait for enough random data entropy (if requested) */ - if (min_entropy > 0) { -diff --git a/src/plugins/crypto.h b/src/plugins/crypto.h -index 71a1438d..a38724d9 100644 ---- a/src/plugins/crypto.h -+++ b/src/plugins/crypto.h -@@ -36,7 +36,7 @@ typedef enum { - /* 20 chars * 6 bits per char (64-item charset) = 120 "bits of security" */ - #define BD_CRYPTO_BACKUP_PASSPHRASE_LENGTH 20 - --#define DEFAULT_LUKS_KEYSIZE_BITS 512 -+#define DEFAULT_LUKS_KEYSIZE_BITS 256 - #define DEFAULT_LUKS_CIPHER "aes-xts-plain64" - #define DEFAULT_LUKS2_SECTOR_SIZE 512 - -diff --git a/tests/crypto_test.py b/tests/crypto_test.py -index 0609a070..0aecc032 100644 ---- a/tests/crypto_test.py -+++ b/tests/crypto_test.py -@@ -236,6 +236,42 @@ def test_luks2_format(self): - self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) - self.assertEqual(int(m.group(1)), 5) - -+ def _get_luks1_key_size(self, device): -+ _ret, out, err = run_command("cryptsetup luksDump %s" % device) -+ m = re.search(r"MK bits:\s*(\S+)\s*", out) -+ if not m or len(m.groups()) != 1: -+ self.fail("Failed to get key size information from:\n%s %s" % (out, err)) -+ key_size = m.group(1) -+ if not key_size.isnumeric(): -+ self.fail("Failed to get key size information from: %s" % key_size) -+ return int(key_size) -+ -+ @tag_test(TestTags.SLOW, TestTags.CORE) -+ def test_luks_format_key_size(self): -+ """Verify that formating device as LUKS works""" -+ -+ # aes-xts: key size should default to 512 -+ succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, PASSWD, None, 0) -+ self.assertTrue(succ) -+ -+ key_size = self._get_luks1_key_size(self.loop_dev) -+ self.assertEqual(key_size, 512) -+ -+ # aes-cbc: key size should default to 256 -+ succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, PASSWD, None, 0) -+ self.assertTrue(succ) -+ -+ key_size = self._get_luks1_key_size(self.loop_dev) -+ self.assertEqual(key_size, 256) -+ -+ # try specifying key size for aes-xts -+ succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 256, PASSWD, None, 0) -+ self.assertTrue(succ) -+ -+ key_size = self._get_luks1_key_size(self.loop_dev) -+ self.assertEqual(key_size, 256) -+ -+ - class CryptoTestResize(CryptoTestCase): - - def _get_key_location(self, device): diff --git a/SOURCES/0005-Add-workarounds-for-some-LVM-test-issues.patch b/SOURCES/0005-Add-workarounds-for-some-LVM-test-issues.patch deleted file mode 100644 index c41d687..0000000 --- a/SOURCES/0005-Add-workarounds-for-some-LVM-test-issues.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 7c31cc534f96766dd2e3427b09d0affca66b0745 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Tue, 23 Mar 2021 13:54:02 +0100 -Subject: [PATCH 1/3] tests: Do not try to remove VG before removing the VDO - pool - ---- - tests/lvm_dbus_tests.py | 6 +++--- - tests/lvm_test.py | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py -index 8f2bb95d..b599fdd0 100644 ---- a/tests/lvm_dbus_tests.py -+++ b/tests/lvm_dbus_tests.py -@@ -1517,14 +1517,14 @@ def setUp(self): - self.assertTrue(succ) - - def _clean_up(self): -- BlockDev.lvm_vgremove("testVDOVG") -- BlockDev.lvm_pvremove(self.loop_dev) -- - try: - BlockDev.lvm_lvremove("testVDOVG", "vdoPool", True, None) - except: - pass - -+ BlockDev.lvm_vgremove("testVDOVG") -+ BlockDev.lvm_pvremove(self.loop_dev) -+ - try: - delete_lio_device(self.loop_dev) - except RuntimeError: -diff --git a/tests/lvm_test.py b/tests/lvm_test.py -index 6f80a3ba..6c04faf9 100644 ---- a/tests/lvm_test.py -+++ b/tests/lvm_test.py -@@ -1437,14 +1437,14 @@ def setUp(self): - self.assertTrue(succ) - - def _clean_up(self): -- BlockDev.lvm_vgremove("testVDOVG") -- BlockDev.lvm_pvremove(self.loop_dev) -- - try: - BlockDev.lvm_lvremove("testVDOVG", "vdoPool", True, None) - except: - pass - -+ BlockDev.lvm_vgremove("testVDOVG") -+ BlockDev.lvm_pvremove(self.loop_dev) -+ - try: - delete_lio_device(self.loop_dev) - except RuntimeError: - -From 41b9d745b8c1a33221e15683f390bae180d1e960 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Tue, 23 Mar 2021 13:59:24 +0100 -Subject: [PATCH 2/3] tests: Force remove LVM VG /dev/ entry not removed by - vgremove - -The directory is sometimes not removed. This is a known bug that -causes subsequent test cases to fail. ---- - tests/lvm_dbus_tests.py | 6 ++++++ - tests/lvm_test.py | 6 ++++++ - 2 files changed, 12 insertions(+) - -diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py -index b599fdd0..3278716e 100644 ---- a/tests/lvm_dbus_tests.py -+++ b/tests/lvm_dbus_tests.py -@@ -399,6 +399,9 @@ def _clean_up(self): - except: - pass - -+ # XXX remove lingering /dev entries -+ shutil.rmtree("/dev/testVG", ignore_errors=True) -+ - LvmPVonlyTestCase._clean_up(self) - - @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") -@@ -1525,6 +1528,9 @@ def _clean_up(self): - BlockDev.lvm_vgremove("testVDOVG") - BlockDev.lvm_pvremove(self.loop_dev) - -+ # XXX remove lingering /dev entries -+ shutil.rmtree("/dev/testVDOVG", ignore_errors=True) -+ - try: - delete_lio_device(self.loop_dev) - except RuntimeError: -diff --git a/tests/lvm_test.py b/tests/lvm_test.py -index 6c04faf9..d7e1f84c 100644 ---- a/tests/lvm_test.py -+++ b/tests/lvm_test.py -@@ -378,6 +378,9 @@ def _clean_up(self): - except: - pass - -+ # XXX remove lingering /dev entries -+ shutil.rmtree("/dev/testVG", ignore_errors=True) -+ - LvmPVonlyTestCase._clean_up(self) - - class LvmTestVGcreateRemove(LvmPVVGTestCase): -@@ -1445,6 +1448,9 @@ def _clean_up(self): - BlockDev.lvm_vgremove("testVDOVG") - BlockDev.lvm_pvremove(self.loop_dev) - -+ # XXX remove lingering /dev entries -+ shutil.rmtree("/dev/testVDOVG", ignore_errors=True) -+ - try: - delete_lio_device(self.loop_dev) - except RuntimeError: - -From 4ecf0075cedf3a1d275d34b94ce5bb512c4e970e Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Tue, 23 Mar 2021 14:03:44 +0100 -Subject: [PATCH 3/3] tests: Tag LvmPVVGLVcachePoolCreateRemoveTestCase as - unstable - -LVM randomly fails to activate the newly created metadata LV. -Issue is reported to LVM and not yet fixed. ---- - tests/lvm_dbus_tests.py | 2 +- - tests/lvm_test.py | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py -index 3278716e..4882da88 100644 ---- a/tests/lvm_dbus_tests.py -+++ b/tests/lvm_dbus_tests.py -@@ -1213,7 +1213,7 @@ def _clean_up(self): - - @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") - class LvmPVVGLVcachePoolCreateRemoveTestCase(LvmPVVGLVcachePoolTestCase): -- @tag_test(TestTags.SLOW) -+ @tag_test(TestTags.SLOW, TestTags.UNSTABLE) - def test_cache_pool_create_remove(self): - """Verify that is it possible to create and remove a cache pool""" - -diff --git a/tests/lvm_test.py b/tests/lvm_test.py -index d7e1f84c..eb94c917 100644 ---- a/tests/lvm_test.py -+++ b/tests/lvm_test.py -@@ -1129,7 +1129,7 @@ def _clean_up(self): - LvmPVVGLVTestCase._clean_up(self) - - class LvmPVVGLVcachePoolCreateRemoveTestCase(LvmPVVGLVcachePoolTestCase): -- @tag_test(TestTags.SLOW) -+ @tag_test(TestTags.SLOW, TestTags.UNSTABLE) - def test_cache_pool_create_remove(self): - """Verify that is it possible to create and remove a cache pool""" - diff --git a/SOURCES/0006-Fix-vdo-stats-calculation.patch b/SOURCES/0006-Fix-vdo-stats-calculation.patch deleted file mode 100644 index f062e55..0000000 --- a/SOURCES/0006-Fix-vdo-stats-calculation.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 2f2dd62b6f6aa61f14f108b95cee7e82f4114614 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Mon, 22 Nov 2021 14:16:02 +0100 -Subject: [PATCH] vdo_stats: Default to 100 % savings for invalid savings - values - -We are currently using "-1" when VDO logical_blocks_used is 0 -which doesn't match the LVM logic which returns 100 so to make -both values in vdo_info and vdo_stats equal we should return 100 -in this case too. ---- - src/plugins/vdo_stats.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/plugins/vdo_stats.c b/src/plugins/vdo_stats.c -index ed04b5101..9f2a24c89 100644 ---- a/src/plugins/vdo_stats.c -+++ b/src/plugins/vdo_stats.c -@@ -96,7 +96,7 @@ static void add_block_stats (GHashTable *stats) { - g_hash_table_replace (stats, g_strdup ("oneKBlocksUsed"), g_strdup_printf ("%"G_GINT64_FORMAT, (data_blocks_used + overhead_blocks_used) * block_size / 1024)); - g_hash_table_replace (stats, g_strdup ("oneKBlocksAvailable"), g_strdup_printf ("%"G_GINT64_FORMAT, (physical_blocks - data_blocks_used - overhead_blocks_used) * block_size / 1024)); - g_hash_table_replace (stats, g_strdup ("usedPercent"), g_strdup_printf ("%.0f", 100.0 * (gfloat) (data_blocks_used + overhead_blocks_used) / (gfloat) physical_blocks + 0.5)); -- savings = (logical_blocks_used > 0) ? (gint64) (100.0 * (gfloat) (logical_blocks_used - data_blocks_used) / (gfloat) logical_blocks_used) : -1; -+ savings = (logical_blocks_used > 0) ? (gint64) (100.0 * (gfloat) (logical_blocks_used - data_blocks_used) / (gfloat) logical_blocks_used) : 100; - g_hash_table_replace (stats, g_strdup ("savings"), g_strdup_printf ("%"G_GINT64_FORMAT, savings)); - if (savings >= 0) - g_hash_table_replace (stats, g_strdup ("savingPercent"), g_strdup_printf ("%"G_GINT64_FORMAT, savings)); diff --git a/SOURCES/0007-ddf-mdadm-uuid-parse-fix.patch b/SOURCES/0007-ddf-mdadm-uuid-parse-fix.patch deleted file mode 100644 index 7206cee..0000000 --- a/SOURCES/0007-ddf-mdadm-uuid-parse-fix.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 9bcaddbe97067f10e643a7d99fa13716126f6e60 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Tue, 25 Aug 2020 14:09:18 +0200 -Subject: [PATCH 1/4] mdraid: Do not ignore errors from bd_md_canonicalize_uuid - in bd_md_examine - ---- - src/plugins/mdraid.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/plugins/mdraid.c b/src/plugins/mdraid.c -index b97bc641..d41b6372 100644 ---- a/src/plugins/mdraid.c -+++ b/src/plugins/mdraid.c -@@ -983,12 +983,24 @@ BDMDExamineData* bd_md_examine (const gchar *device, GError **error) { - orig_data = ret->uuid; - if (orig_data) { - ret->uuid = bd_md_canonicalize_uuid (orig_data, error); -+ if (!ret->uuid) { -+ g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", orig_data); -+ g_free (orig_data); -+ bd_md_examine_data_free (ret); -+ return NULL; -+ } - g_free (orig_data); - } - - orig_data = ret->dev_uuid; - if (orig_data) { - ret->dev_uuid = bd_md_canonicalize_uuid (orig_data, error); -+ if (!ret->uuid) { -+ g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", orig_data); -+ g_free (orig_data); -+ bd_md_examine_data_free (ret); -+ return NULL; -+ } - g_free (orig_data); - } - --- -2.37.1 - - -From 1805734e8315d5fb73f036dae043312c88f3c3ec Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Tue, 25 Aug 2020 14:12:52 +0200 -Subject: [PATCH 2/4] mdraid: Try harder to get container UUID in bd_md_examine - -For containers UUID is not printed in 'mdadm --examine' but it is -printed when using the '--export' option. ---- - src/plugins/mdraid.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/plugins/mdraid.c b/src/plugins/mdraid.c -index d41b6372..3a23cf2e 100644 ---- a/src/plugins/mdraid.c -+++ b/src/plugins/mdraid.c -@@ -1023,6 +1023,17 @@ BDMDExamineData* bd_md_examine (const gchar *device, GError **error) { - value++; - g_free (ret->level); - ret->level = g_strdup (value); -+ } else if (!ret->uuid && g_str_has_prefix (output_fields[i], "MD_UUID=")) { -+ value = strchr (output_fields[i], '='); -+ value++; -+ ret->uuid = bd_md_canonicalize_uuid (value, error); -+ if (!ret->uuid) { -+ g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", orig_data); -+ g_free (orig_data); -+ bd_md_examine_data_free (ret); -+ g_strfreev (output_fields); -+ return NULL; -+ } - } - g_strfreev (output_fields); - --- -2.37.1 - - -From 166756338f90d90b32ae0989db706dd52f7df234 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Thu, 4 Aug 2022 12:47:53 +0200 -Subject: [PATCH 3/4] mdraid: Try harder to get container UUID in bd_md_detail - -Similarly to bd_md_examine (see a10ad4e0), "mdadm --detail" -doesn't contain container UUID, we need to need "--export" for -that. ---- - src/plugins/mdraid.c | 43 +++++++++++++++++++++++++++++++++++-------- - 1 file changed, 35 insertions(+), 8 deletions(-) - -diff --git a/src/plugins/mdraid.c b/src/plugins/mdraid.c -index 3a23cf2e..67bdc1f9 100644 ---- a/src/plugins/mdraid.c -+++ b/src/plugins/mdraid.c -@@ -1093,13 +1093,16 @@ BDMDExamineData* bd_md_examine (const gchar *device, GError **error) { - * Tech category: %BD_MD_TECH_MDRAID-%BD_MD_TECH_MODE_QUERY - */ - BDMDDetailData* bd_md_detail (const gchar *raid_spec, GError **error) { -- const gchar *argv[] = {"mdadm", "--detail", NULL, NULL}; -+ const gchar *argv[] = {"mdadm", "--detail", NULL, NULL, NULL}; - gchar *output = NULL; - gboolean success = FALSE; - GHashTable *table = NULL; - guint num_items = 0; - gchar *orig_uuid = NULL; -- gchar *mdadm_spec = NULL; -+ g_autofree gchar *mdadm_spec = NULL; -+ gchar *value = NULL; -+ gchar **output_fields = NULL; -+ guint i = 0; - BDMDDetailData *ret = NULL; - - if (!check_deps (&avail_deps, DEPS_MDADM_MASK, deps, DEPS_LAST, &deps_check_lock, error)) -@@ -1113,16 +1116,13 @@ BDMDDetailData* bd_md_detail (const gchar *raid_spec, GError **error) { - argv[2] = mdadm_spec; - - success = bd_utils_exec_and_capture_output (argv, NULL, &output, error); -- if (!success) { -- g_free (mdadm_spec); -+ if (!success) - /* error is already populated */ - return NULL; -- } - - table = parse_mdadm_vars (output, "\n", ":", &num_items); - g_free (output); - if (!table || (num_items == 0)) { -- g_free (mdadm_spec); - /* something bad happened or some expected items were missing */ - g_set_error (error, BD_MD_ERROR, BD_MD_ERROR_PARSE, "Failed to parse mddetail data"); - if (table) -@@ -1132,7 +1132,6 @@ BDMDDetailData* bd_md_detail (const gchar *raid_spec, GError **error) { - - ret = get_detail_data_from_table (table, TRUE); - if (!ret) { -- g_free (mdadm_spec); - g_set_error (error, BD_MD_ERROR, BD_MD_ERROR_PARSE, "Failed to get mddetail data"); - return NULL; - } -@@ -1145,7 +1144,35 @@ BDMDDetailData* bd_md_detail (const gchar *raid_spec, GError **error) { - g_free (orig_uuid); - } - -- g_free (mdadm_spec); -+ if (!ret->uuid) { -+ argv[2] = "--export"; -+ argv[3] = mdadm_spec; -+ success = bd_utils_exec_and_capture_output (argv, NULL, &output, error); -+ if (!success) { -+ /* error is already populated */ -+ bd_md_detail_data_free (ret); -+ return NULL; -+ } -+ -+ /* try to get a better information about RAID level because it may be -+ missing in the output without --export */ -+ output_fields = g_strsplit (output, "\n", 0); -+ g_free (output); -+ output = NULL; -+ for (i = 0; (i < g_strv_length (output_fields) - 1); i++) -+ if (g_str_has_prefix (output_fields[i], "MD_UUID=")) { -+ value = strchr (output_fields[i], '='); -+ value++; -+ ret->uuid = bd_md_canonicalize_uuid (value, error); -+ if (!ret->uuid) { -+ g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", value); -+ bd_md_detail_data_free (ret); -+ g_strfreev (output_fields); -+ return NULL; -+ } -+ } -+ g_strfreev (output_fields); -+ } - - return ret; - } --- -2.37.1 - - -From 25dd2f8c7cc3cf540902fc40e808faabda3c691a Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Thu, 4 Aug 2022 12:51:48 +0200 -Subject: [PATCH 4/4] Add a test case for DDF arrays/containers - ---- - tests/mdraid_test.py | 51 ++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 47 insertions(+), 4 deletions(-) - -diff --git a/tests/mdraid_test.py b/tests/mdraid_test.py -index 0b2bdc9b..38f43a0d 100644 ---- a/tests/mdraid_test.py -+++ b/tests/mdraid_test.py -@@ -6,7 +6,7 @@ from contextlib import contextmanager - import overrides_hack - import six - --from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, TestTags, tag_test -+from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, TestTags, tag_test, run_command - from gi.repository import BlockDev, GLib - - -@@ -90,14 +90,16 @@ class MDNoDevTestCase(MDTest): - - class MDTestCase(MDTest): - -+ _sparse_size = 10 * 1024**2 -+ - def setUp(self): - if os.uname()[-1] == "i686": - self.skipTest("Skipping hanging MD RAID tests on i686") - - self.addCleanup(self._clean_up) -- self.dev_file = create_sparse_tempfile("md_test", 10 * 1024**2) -- self.dev_file2 = create_sparse_tempfile("md_test", 10 * 1024**2) -- self.dev_file3 = create_sparse_tempfile("md_test", 10 * 1024**2) -+ self.dev_file = create_sparse_tempfile("md_test", self._sparse_size) -+ self.dev_file2 = create_sparse_tempfile("md_test", self._sparse_size) -+ self.dev_file3 = create_sparse_tempfile("md_test", self._sparse_size) - - try: - self.loop_dev = create_lio_device(self.dev_file) -@@ -586,6 +588,47 @@ class MDTestRequestSyncAction(MDTestCase): - action = f.read().strip() - self.assertEqual(action, "check") - -+ -+class MDTestDDFRAID(MDTestCase): -+ -+ _sparse_size = 50 * 1024**2 -+ -+ def _clean_up(self): -+ try: -+ BlockDev.md_deactivate("bd_test_ddf") -+ except: -+ pass -+ try: -+ BlockDev.md_deactivate(BlockDev.md_node_from_name("bd_test_ddf")) -+ except: -+ pass -+ -+ super(MDTestDDFRAID, self)._clean_up() -+ -+ def test_examine_ddf_container(self): -+ succ = BlockDev.md_create("bd_test_md", "container", -+ [self.loop_dev, self.loop_dev2], -+ 0, "ddf", False) -+ self.assertTrue(succ) -+ -+ # we cannot create the array with libblockdev because we cannot pass the --raid-devices option -+ ret, _out, err = run_command("mdadm --create /dev/md/bd_test_ddf --run --level=raid0 --raid-devices=2 /dev/md/bd_test_md") -+ self.assertEqual(ret, 0, msg="Failed to create RAID for DDF test: %s" % err) -+ -+ edata = BlockDev.md_examine(self.loop_dev) -+ self.assertIsNotNone(edata) -+ self.assertIsNotNone(edata.uuid) -+ self.assertEqual(edata.level, "container") -+ self.assertEqual(edata.metadata, "ddf") -+ -+ ddata = BlockDev.md_detail("bd_test_md") -+ self.assertIsNotNone(ddata) -+ self.assertIsNotNone(ddata.uuid) -+ self.assertEqual(ddata.uuid, edata.uuid) -+ self.assertEqual(ddata.level, "container") -+ self.assertEqual(ddata.metadata, "ddf") -+ -+ - class FakeMDADMutilTest(MDTest): - # no setUp nor tearDown needed, we are gonna use fake utils - @tag_test(TestTags.NOSTORAGE) --- -2.37.1 - diff --git a/SOURCES/0008-mdraid-Fix-copy-paste-error-when-checking-return-val.patch b/SOURCES/0008-mdraid-Fix-copy-paste-error-when-checking-return-val.patch deleted file mode 100644 index e977e90..0000000 --- a/SOURCES/0008-mdraid-Fix-copy-paste-error-when-checking-return-val.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 8d26fe554dc057566b722b895aa48092ea0f2f64 Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Fri, 25 Sep 2020 14:26:57 +0200 -Subject: [PATCH] mdraid: Fix copy-paste error when checking return value - ---- - src/plugins/mdraid.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/plugins/mdraid.c b/src/plugins/mdraid.c -index 24f01bcb..eaf659d3 100644 ---- a/src/plugins/mdraid.c -+++ b/src/plugins/mdraid.c -@@ -995,7 +995,7 @@ BDMDExamineData* bd_md_examine (const gchar *device, GError **error) { - orig_data = ret->dev_uuid; - if (orig_data) { - ret->dev_uuid = bd_md_canonicalize_uuid (orig_data, error); -- if (!ret->uuid) { -+ if (!ret->dev_uuid) { - g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", orig_data); - g_free (orig_data); - bd_md_examine_data_free (ret); --- -2.37.1 - diff --git a/SOURCES/0009-mdraid-Fix-use-after-free.patch b/SOURCES/0009-mdraid-Fix-use-after-free.patch deleted file mode 100644 index 49a1cf1..0000000 --- a/SOURCES/0009-mdraid-Fix-use-after-free.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 658c07e92eff05d99a65f112161ea82da842cd2d Mon Sep 17 00:00:00 2001 -From: Vojtech Trefny -Date: Fri, 25 Sep 2020 14:41:20 +0200 -Subject: [PATCH] mdraid: Fix use after free - -Another copy-paste error. ---- - src/plugins/mdraid.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/src/plugins/mdraid.c b/src/plugins/mdraid.c -index eaf659d3..11067c95 100644 ---- a/src/plugins/mdraid.c -+++ b/src/plugins/mdraid.c -@@ -1028,8 +1028,7 @@ BDMDExamineData* bd_md_examine (const gchar *device, GError **error) { - value++; - ret->uuid = bd_md_canonicalize_uuid (value, error); - if (!ret->uuid) { -- g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", orig_data); -- g_free (orig_data); -+ g_prefix_error (error, "Failed to canonicalize MD UUID '%s': ", value); - bd_md_examine_data_free (ret); - g_strfreev (output_fields); - return NULL; --- -2.37.1 - diff --git a/SPECS/libblockdev.spec b/SPECS/libblockdev.spec index 8adc994..1feefb7 100644 --- a/SPECS/libblockdev.spec +++ b/SPECS/libblockdev.spec @@ -124,22 +124,15 @@ %define configure_opts %{?python2_copts} %{?python3_copts} %{?bcache_copts} %{?lvm_dbus_copts} %{?btrfs_copts} %{?crypto_copts} %{?dm_copts} %{?loop_copts} %{?lvm_copts} %{?lvm_dbus_copts} %{?mdraid_copts} %{?mpath_copts} %{?swap_copts} %{?kbd_copts} %{?part_copts} %{?fs_copts} %{?nvdimm_copts} %{?vdo_copts} %{?tools_copts} %{?gi_copts} Name: libblockdev -Version: 2.24 -Release: 11%{?dist} +Version: 2.28 +Release: 2%{?dist} Summary: A library for low-level manipulation with block devices License: LGPLv2+ URL: https://github.com/storaged-project/libblockdev Source0: https://github.com/storaged-project/libblockdev/releases/download/%{version}-%{release}/%{name}-%{version}.tar.gz -Patch0: 0001-exec-Fix-setting-locale-for-util-calls.patch -Patch1: 0002-exec-polling-fixes.patch -Patch2: 0003-LVM-thin-metadata-calculation-fix.patch -Patch3: 0004-Fix-default-key-size-for-non-XTS-ciphers.patch -Patch4: 0005-Add-workarounds-for-some-LVM-test-issues.patch -Patch5: 0006-Fix-vdo-stats-calculation.patch -Patch6: 0007-ddf-mdadm-uuid-parse-fix.patch -Patch7: 0008-mdraid-Fix-copy-paste-error-when-checking-return-val.patch -Patch8: 0009-mdraid-Fix-use-after-free.patch +Patch0: 0001-crypto-Fix-GError-overwrite-from-libvolume_key.patch +BuildRequires: make BuildRequires: glib2-devel %if %{with_gi} BuildRequires: gobject-introspection-devel @@ -182,6 +175,7 @@ no information about VGs when creating an LV). Summary: Development files for libblockdev Requires: %{name}%{?_isa} = %{version}-%{release} Requires: glib2-devel +Requires: %{name}-utils-devel%{?_isa} = %{version}-%{release} %description devel This package contains header files and pkg-config files needed for development @@ -259,6 +253,7 @@ with the libblockdev-btrfs plugin/library. %if %{with_crypto} %package crypto +Requires: %{name}-utils%{?_isa} = %{version}-%{release} BuildRequires: cryptsetup-devel BuildRequires: libblkid-devel @@ -268,7 +263,6 @@ BuildRequires: nss-devel %endif Summary: The crypto plugin for the libblockdev library -Requires: %{name}-utils%{?_isa} = %{version}-%{release} %description crypto The libblockdev library plugin (and in the same time a standalone library) @@ -400,8 +394,6 @@ BuildRequires: device-mapper-devel Summary: The LVM plugin for the libblockdev library Requires: %{name}-utils%{?_isa} = %{version}-%{release} Requires: lvm2 -# for thin_metadata_size -Requires: device-mapper-persistent-data %description lvm The libblockdev library plugin (and in the same time a standalone library) @@ -424,8 +416,6 @@ BuildRequires: device-mapper-devel Summary: The LVM plugin for the libblockdev library Requires: %{name}-utils%{?_isa} = %{version}-%{release} Requires: lvm2-dbusd >= 2.02.156 -# for thin_metadata_size -Requires: device-mapper-persistent-data %description lvm-dbus The libblockdev library plugin (and in the same time a standalone library) @@ -595,8 +585,8 @@ with the libblockdev-vdo plugin/library. %if %{with_tools} %package tools Summary: Various nice tools based on libblockdev -Requires: %{name} -Requires: %{name}-lvm +Requires: %{name} = %{version}-%{release} +Requires: %{name}-lvm = %{version}-%{release} BuildRequires: libbytesize-devel %if %{with_lvm_dbus} == 1 Recommends: %{name}-lvm-dbus @@ -695,14 +685,6 @@ A meta-package that pulls all the libblockdev plugins as dependencies. %prep %setup -q -n %{name}-%{version} %patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 %build autoreconf -ivf @@ -1006,6 +988,14 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %files plugins-all %changelog +* Wed Nov 30 2022 Vojtech Trefny - 2.28-2 +- Fix double free in write_escrow_data_file + Resolves: rhbz#2142660 + +* Wed Sep 14 2022 Vojtech Trefny - 2.28-1 +- Rebase to the latest upstream release 2.28 + Resolves: rhbz#2123347 + * Mon Aug 08 2022 Vojtech Trefny - 2.24-11 - mdraid: Fix use after free Related: rhbz#2078815