diff mbox series

[v1,2/2] diskpart: format only if filesystem not exists

Message ID 20210728140238.8708-3-roland.gaudig-oss@weidmueller.com
State Changes Requested
Headers show
Series handlers: diskpart: Add check for existing filesystem | expand

Commit Message

Roland Gaudig July 28, 2021, 2:02 p.m. UTC
From: Roland Gaudig <roland.gaudig@gaudig.com>

There are use cases where already a filesystem might have been created
before, which should not be overwritten.

This commit adds a new configuration option DISKFORMAT_CHECK_OVERWRITE,
which enables a check whether the requested file system already exists on
the partition. If it alreay exists, the partition won't be formatted.

In case there is already a file system of another type than requested, the
partition will be formatted with the new file system type.

Signed-off-by: Roland Gaudig <roland.gaudig@gaudig.com>
Signed-off-by: Roland Gaudig <roland.gaudig@weidmueller.com>
---

 Makefile.flags              |  6 ++++-
 handlers/Config.in          | 11 ++++++++
 handlers/diskpart_handler.c | 54 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 69 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/Makefile.flags b/Makefile.flags
index d3ca49d..56ffdfb 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -1,4 +1,4 @@ 
-# SPDX-FileCopyrightText: 2013 Stefano Babic <sbabic@denx.de>
+ # SPDX-FileCopyrightText: 2013 Stefano Babic <sbabic@denx.de>
 #
 # SPDX-License-Identifier: GPL-2.0-only
 
@@ -185,6 +185,10 @@  ifeq ($(CONFIG_DISKPART),y)
 LDLIBS += fdisk
 endif
 
+ifeq ($(CONFIG_DISKFORMAT_CHECK_OVERWRITE),y)
+LDLIBS += blkid
+endif
+
 ifeq ($(CONFIG_EXT_FILESYSTEM),y)
 LDLIBS += ext2fs uuid blkid
 endif
diff --git a/handlers/Config.in b/handlers/Config.in
index bfc8d19..d8d7193 100644
--- a/handlers/Config.in
+++ b/handlers/Config.in
@@ -126,6 +126,17 @@  config DISKFORMAT_IGNORE_PT_CHANGE
 	  partition activating this option allows creating a filesystem even
 	  when the partition table remains unchaned.
 
+config DISKFORMAT_CHECK_OVERWRITE
+	bool "Preserve file system if already exists"
+	depends on HAVE_LIBBLKID
+	depends on DISKFORMAT
+	default n
+	help
+	  This option enables a check whether the file system requested already
+	  exists on the partition. In case it already exists, it won't be
+	  overwritten. In cae there exists already a file system of another
+	  type, the partition will be formatted with the new file system type.
+
 if DISKFORMAT
 
 source fs/Config.in
diff --git a/handlers/diskpart_handler.c b/handlers/diskpart_handler.c
index 85dfb10..3cbedcc 100644
--- a/handlers/diskpart_handler.c
+++ b/handlers/diskpart_handler.c
@@ -21,6 +21,10 @@ 
 #include "util.h"
 #include "fs_interface.h"
 
+#ifdef CONFIG_DISKFORMAT_CHECK_OVERWRITE
+#include <blkid/blkid.h>
+#endif
+
 void diskpart_handler(void);
 
 /*
@@ -737,6 +741,45 @@  static int diskpart_write_table(struct fdisk_context *cxt, struct create_table *
 	return ret;
 }
 
+#ifdef CONFIG_DISKFORMAT_CHECK_OVERWRITE
+/*
+ * Checks if filesystem fstype already exists on device.
+ * return 0 if not exists, 1 if exists, negative values on failure
+ */
+static int fs_exists(char *device, char *fstype)
+{
+	char buf[10];
+	const char *value = buf;
+	size_t len;
+	blkid_probe pr;
+	int ret = 0;
+
+	pr = blkid_new_probe_from_filename(device);
+
+	if (!pr) {
+		ERROR("%s: failed to create libblkid probe",
+		      device);
+		return -EFAULT;
+	}
+
+	while (blkid_do_probe(pr) == 0) {
+		if (blkid_probe_lookup_value(pr, "TYPE", &value, &len)) {
+			ERROR("blkid_probe_lookup_value failed");
+			ret = -EFAULT;
+			break;
+		}
+
+		if (!strncmp(value, fstype, sizeof(buf))) {
+			ret = 1;
+			break;
+		}
+	}
+	blkid_free_probe(pr);
+
+	return ret;
+}
+#endif
+
 static int diskpart(struct img_type *img,
 	void __attribute__ ((__unused__)) *data)
 {
@@ -935,7 +978,6 @@  handler_release:
 	 * that SWUpdate does not try to access the partitions before the kernel is
 	 * ready
 	 */
-
 	sleep(2);
 
 #ifdef CONFIG_DISKFORMAT
@@ -968,6 +1010,16 @@  handler_release:
 
 			char *device = NULL;
 			device = fdisk_partname(img->device, partno);
+#ifdef CONFIG_DISKFORMAT_CHECK_OVERWRITE
+			ret = fs_exists(device, part->fstype);
+			if (ret < 0)
+				break;
+			if (ret) {
+				TRACE("%s file system already on partition-%lu, device %s, skip creation",
+				      part->fstype, partno, device);
+				continue;
+			}
+#endif
 			TRACE("Creating %s file system on partition-%lu, device %s", part->fstype, partno, device);
 			ret = fs[index].mkfs(device, part->fstype);
 			free(device);