@@ -185,6 +185,10 @@ ifeq ($(CONFIG_DISKPART),y)
LDLIBS += fdisk
endif
+ifeq ($(CONFIG_DISKFORMAT_HANDLER),y)
+LDLIBS += blkid
+endif
+
ifeq ($(CONFIG_EXT_FILESYSTEM),y)
LDLIBS += ext2fs uuid blkid
endif
@@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: GPL-2.0-only
+lib-$(CONFIG_DISKFORMAT) += diskformat.o
lib-$(CONFIG_FAT_FILESYSTEM) += diskio.o \
fat_fs.o \
ff.o
new file mode 100644
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
+ * Roland Gaudig <roland.gaudig@weidmueller.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <util.h>
+#include <handler.h>
+#include <blkid/blkid.h>
+#include <fs_interface.h>
+
+#if defined(CONFIG_EXT_FILESYSTEM)
+static inline int ext_mkfs_short(const char *device_name, const char *fstype)
+{
+ return ext_mkfs(device_name, fstype, 0, NULL);
+}
+#endif
+
+struct supported_filesystems {
+ const char *fstype;
+ int (*mkfs)(const char *device_name, const char *fstype);
+};
+
+static struct supported_filesystems fs[] = {
+#if defined(CONFIG_FAT_FILESYSTEM)
+ {"vfat", fat_mkfs},
+#endif
+#if defined(CONFIG_EXT_FILESYSTEM)
+ {"ext2", ext_mkfs_short},
+ {"ext3", ext_mkfs_short},
+ {"ext4", ext_mkfs_short},
+#endif
+};
+
+int diskformat_mkfs(char *device, char *fstype)
+{
+ int index;
+ int ret = 0;
+
+ if (!device || !fstype) {
+ ERROR("Uninitialized pointer as device/fstype argument");
+ return -EINVAL;
+ }
+
+ for (index = 0; index < ARRAY_SIZE(fs); index++) {
+ if (!strcmp(fs[index].fstype, fstype))
+ break;
+ }
+ if (index >= ARRAY_SIZE(fs)) {
+ ERROR("%s file system type not supported.", fstype);
+ return -EINVAL;
+ }
+
+ TRACE("Creating %s file system on %s", fstype, device);
+ ret = fs[index].mkfs(device, fstype);
+
+ if (ret) {
+ ERROR("creating %s file system on %s failed. %d",
+ fstype, device, ret);
+ return -EFAULT;
+ }
+
+ return ret;
+}
@@ -106,15 +106,19 @@ config DISKPART
comment "diskpart support needs libfdisk"
depends on !HAVE_LIBFDISK
-if DISKPART
-
-menuconfig DISKFORMAT
- bool "diskpart extension for creating file systems"
+config DISKFORMAT
+ bool "diskpart extension for creating file systems"
depends on DISKPART
+ help
+ This extension allows formatting newly created partitions.
+
+config DISKFORMAT_HANDLER
+ bool "diskformat handler for creating file systems"
+ select DISKFORMAT
default n
help
- This extension of the diskpart handler allows creating filesystems
- on empty partitions.
+ The diskformat handler allows creating filesystems on empty
+ partitions.
if DISKFORMAT
@@ -122,8 +126,6 @@ source fs/Config.in
endif
-endif
-
config UNIQUEUUID
bool "uniqueuuid"
depends on HAVE_LIBBLKID
@@ -11,6 +11,7 @@ obj-y += dummy_handler.o
obj-$(CONFIG_ARCHIVE) += archive_handler.o
obj-$(CONFIG_BOOTLOADERHANDLER) += boot_handler.o
obj-$(CONFIG_CFI) += flash_handler.o
+obj-$(CONFIG_DISKFORMAT_HANDLER) += diskformat_handler.o
obj-$(CONFIG_DISKPART) += diskpart_handler.o
obj-$(CONFIG_UNIQUEUUID) += uniqueuuid_handler.o
obj-$(CONFIG_CFIHAMMING1)+= flash_hamming1_handler.o
new file mode 100644
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
+ * Roland Gaudig <roland.gaudig@weidmueller.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <util.h>
+#include <handler.h>
+#include <blkid/blkid.h>
+#include <fs_interface.h>
+
+void diskformat_handler(void);
+
+/*
+ * Checks if file system 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;
+}
+
+static int diskformat(struct img_type *img,
+ void __attribute__ ((__unused__)) *data)
+{
+ int ret = 0;
+
+ if (!strlen(img->device)) {
+ ERROR("diskpart handler requires setting \"device\" attribute");
+ return -EINVAL;
+ }
+
+ char *fstype = dict_get_value(&img->properties, "fstype");
+
+ if (!fstype) {
+ ERROR("diskpart handler requires setting \"fstype\" attribute");
+ return -EINVAL;
+ }
+
+ char *force = dict_get_value(&img->properties, "force");
+
+ if (force != NULL && strcmp(force, "true") == 0) {
+ ; /* Skip file system exists check */
+ } else {
+ /* Check if file system exists */
+ ret = fs_exists(img->device, fstype);
+
+ if (ret < 0)
+ return ret;
+
+ if (ret) {
+ TRACE("Found %s file system on %s, skip mkfs",
+ fstype, img->device);
+ return 0;
+ }
+ }
+
+ /* File system does not exist, create new file system */
+ ret = diskformat_mkfs(img->device, fstype);
+ return ret;
+}
+
+__attribute__((constructor))
+void diskformat_handler(void)
+{
+ register_handler("diskformat", diskformat,
+ PARTITION_HANDLER | NO_DATA_HANDLER, NULL);
+}
@@ -16,10 +16,10 @@
#include <sys/file.h>
#include <sys/types.h>
#include <libfdisk/libfdisk.h>
+#include <fs_interface.h>
#include "swupdate.h"
#include "handler.h"
#include "util.h"
-#include "fs_interface.h"
void diskpart_handler(void);
@@ -31,12 +31,6 @@ void diskpart_handler(void);
/* Linux native partition type */
#define GPT_DEFAULT_ENTRY_TYPE "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
-#if defined (CONFIG_EXT_FILESYSTEM)
-static inline int ext_mkfs_short(const char *device_name, const char *fstype) {
- return ext_mkfs(device_name,fstype, 0, NULL);
-}
-#endif
-
/*
* We will only have a parent in hybrid mode.
*/
@@ -47,22 +41,6 @@ static inline int ext_mkfs_short(const char *device_name, const char *fstype) {
*/
#define PARENT(cxt) fdisk_get_parent(cxt) ? fdisk_get_parent(cxt) : cxt
-struct supported_filesystems {
- const char *fstype;
- int (*mkfs) (const char *device_name, const char *fstype);
-};
-
-static struct supported_filesystems fs[] = {
-#if defined(CONFIG_FAT_FILESYSTEM)
- {"vfat", fat_mkfs},
-#endif
-#if defined (CONFIG_EXT_FILESYSTEM)
- {"ext2", ext_mkfs_short},
- {"ext3", ext_mkfs_short},
- {"ext4", ext_mkfs_short},
-#endif
-};
-
/**
* Keys for the properties field in sw-description
*/
@@ -942,7 +920,6 @@ handler_release:
/* Create filesystems */
if (!ret && createtable->parent) {
LIST_FOREACH(part, &priv.listparts, next) {
- int index;
/*
* priv.listparts counts partitions starting with 0,
* but fdisk_partname expects the first partition having
@@ -952,25 +929,14 @@ handler_release:
if (!strlen(part->fstype))
continue; /* Don't touch partitions without fstype */
- for (index = 0; index < ARRAY_SIZE(fs); index++) {
- if (!strcmp(fs[index].fstype, part->fstype))
- break;
- }
- if (index >= ARRAY_SIZE(fs)) {
- ERROR("partition-%lu %s filesystem type not supported.", partno, part->fstype);
- ret = -EINVAL;
- break;
- }
char *device = NULL;
+
device = fdisk_partname(img->device, partno);
- TRACE("Creating %s file system on partition-%lu, device %s", part->fstype, partno, device);
- ret = fs[index].mkfs(device, part->fstype);
+ ret = diskformat_mkfs(device, part->fstype);
free(device);
- if (ret) {
- ERROR("creating %s file system failed. %d", part->fstype, ret);
+ if (ret)
break;
- }
}
}
#endif
@@ -7,6 +7,8 @@
#ifndef _FS_INTERFACE_H
#define _FS_INTERFACE_H
+int diskformat_mkfs(char *device, char *fstype);
+
#if defined(CONFIG_FAT_FILESYSTEM)
extern int fat_mkfs(const char *device_name, const char *fstype);
#endif