Blame SOURCES/0040-writecache-check-memory-usage.patch

4d51e5
From 10a598075a0fdf6d93cc2fefa73fc4a5f1d0de48 Mon Sep 17 00:00:00 2001
4d51e5
From: David Teigland <teigland@redhat.com>
4d51e5
Date: Tue, 1 Mar 2022 14:31:39 -0600
4d51e5
Subject: [PATCH 40/54] writecache: check memory usage
4d51e5
4d51e5
warn if writecache neds > 50% of system memory, and
4d51e5
confirm if writecache needs > 90% of system memory.
4d51e5
---
4d51e5
 tools/lvconvert.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
4d51e5
 1 file changed, 69 insertions(+)
4d51e5
4d51e5
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
4d51e5
index 34b82ea02..a90946173 100644
4d51e5
--- a/tools/lvconvert.c
4d51e5
+++ b/tools/lvconvert.c
4d51e5
@@ -6072,6 +6072,69 @@ bad:
4d51e5
 	return 0;
4d51e5
 }
4d51e5
 
4d51e5
+static int _check_writecache_memory(struct cmd_context *cmd, struct logical_volume *lv_fast,
4d51e5
+				     uint32_t block_size_sectors)
4d51e5
+{
4d51e5
+	char line[128];
4d51e5
+	FILE *fp;
4d51e5
+	uint64_t cachevol_size_bytes = lv_fast->size * SECTOR_SIZE;
4d51e5
+	uint64_t need_mem_bytes = 0;
4d51e5
+	uint64_t proc_mem_bytes = 0;
4d51e5
+	uint64_t need_mem_gb;
4d51e5
+	uint64_t proc_mem_gb;
4d51e5
+	unsigned long long proc_mem_kb = 0;
4d51e5
+
4d51e5
+	if (!(fp = fopen("/proc/meminfo", "r")))
4d51e5
+		goto skip_proc;
4d51e5
+
4d51e5
+	while (fgets(line, sizeof(line), fp)) {
4d51e5
+		if (strncmp(line, "MemTotal:", 9))
4d51e5
+			continue;
4d51e5
+		if (sscanf(line, "%*s%llu%*s", &proc_mem_kb) != 1)
4d51e5
+			break;
4d51e5
+		break;
4d51e5
+	}
4d51e5
+	(void)fclose(fp);
4d51e5
+
4d51e5
+	proc_mem_bytes = proc_mem_kb * 1024;
4d51e5
+
4d51e5
+ skip_proc:
4d51e5
+	/* dm-writecache memory consumption per block is 88 bytes */
4d51e5
+	if (block_size_sectors == 8) {
4d51e5
+		need_mem_bytes = cachevol_size_bytes * 88 / 4096;
4d51e5
+	} else if (block_size_sectors == 1) {
4d51e5
+		need_mem_bytes = cachevol_size_bytes * 88 / 512;
4d51e5
+	} else {
4d51e5
+		/* shouldn't happen */
4d51e5
+		log_warn("Unknown memory usage for unknown writecache block_size_sectors %u", block_size_sectors);
4d51e5
+		return 1;
4d51e5
+	}
4d51e5
+
4d51e5
+	need_mem_gb = need_mem_bytes / 1073741824;
4d51e5
+	proc_mem_gb = proc_mem_bytes / 1073741824;
4d51e5
+
4d51e5
+	/*
4d51e5
+	 * warn if writecache needs > 50% of main memory, and
4d51e5
+	 * confirm if writecache needs > 90% of main memory.
4d51e5
+	 */
4d51e5
+	if (need_mem_bytes >= (proc_mem_bytes / 2)) {
4d51e5
+		log_warn("WARNING: writecache size %s will use %llu GiB of system memory (%llu GiB).",
4d51e5
+			  display_size(cmd, lv_fast->size),
4d51e5
+			  (unsigned long long)need_mem_gb,
4d51e5
+			  (unsigned long long)proc_mem_gb);
4d51e5
+
4d51e5
+		if (need_mem_gb >= (proc_mem_gb * 9 / 10)) {
4d51e5
+			if (!arg_is_set(cmd, yes_ARG) &&
4d51e5
+			    yes_no_prompt("Continue adding writecache? [y/n]: ") == 'n') {
4d51e5
+				log_error("Conversion aborted.");
4d51e5
+				return 0;
4d51e5
+			}
4d51e5
+		}
4d51e5
+	}
4d51e5
+
4d51e5
+	return 1;
4d51e5
+}
4d51e5
+
4d51e5
 int lvconvert_writecache_attach_single(struct cmd_context *cmd,
4d51e5
 					struct logical_volume *lv,
4d51e5
 					struct processing_handle *handle)
4d51e5
@@ -6160,6 +6223,12 @@ int lvconvert_writecache_attach_single(struct cmd_context *cmd,
4d51e5
 		goto_bad;
4d51e5
 	}
4d51e5
 
4d51e5
+	if (!_check_writecache_memory(cmd, lv_fast, block_size_sectors)) {
4d51e5
+		if (!is_active && !deactivate_lv(cmd, lv))
4d51e5
+			stack;
4d51e5
+		goto_bad;
4d51e5
+	}
4d51e5
+
4d51e5
 	if (!is_active) {
4d51e5
 		if (!deactivate_lv(cmd, lv)) {
4d51e5
 			log_error("Failed to deactivate LV after checking block size %s", display_lvname(lv));
4d51e5
-- 
4d51e5
2.34.3
4d51e5