[OpenWrt-Devel] [PATCH] support for ext4fs overlay
John Crispin
john at phrozen.org
Thu Mar 10 14:26:11 EST 2016
Hi,
thanks for the patch. please use the prefix "fstools: " in the subject
see inline for more nitpicks
On 10/03/2016 12:47, Ram Chandra Jangir wrote:
> This change will enables eMMC (ext4 fs) boot support, when we try to boot
> from eMMC card then it will read partition names from
> /sys/block/mmcblkX/mmcblkXY/uevent
> file and will mount the rootfs_data partition as ext4fs overlay.
>
> During firstboot, it will format the rootfs_data partition and will
> switch from tmpfs to ext4fs overlay.
>
> Signed-off-by: Ram Chandra Jangir <rjangi at codeaurora.org>
> ---
> CMakeLists.txt | 1 +
> libfstools/ext4.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++
> libfstools/find.c | 3 +-
> libfstools/libfstools.h | 1 +
> libfstools/overlay.c | 22 +++++-
> mount_root.c | 1 +
> 6 files changed, 218 insertions(+), 2 deletions(-)
> create mode 100644 libfstools/ext4.c
>
> diff --git a/CMakeLists.txt b/CMakeLists.txt
> index a6002e5..5117e8e 100644
> --- a/CMakeLists.txt
> +++ b/CMakeLists.txt
> @@ -11,6 +11,7 @@ ADD_LIBRARY(fstools SHARED
> libfstools/overlay.c
> libfstools/volume.c
> libfstools/mtd.c
> + libfstools/ext4.c
> libfstools/mount.c
> libfstools/ubi.c
> libfstools/find.c)
> diff --git a/libfstools/ext4.c b/libfstools/ext4.c
> new file mode 100644
> index 0000000..8a263ac
> --- /dev/null
> +++ b/libfstools/ext4.c
> @@ -0,0 +1,192 @@
> +/*
> + * Copyright (c) 2016, The Linux Foundation. All rights reserved.
> + *
> + * Permission to use, copy, modify, and/or distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +*/
> +
> +
> +#include <sys/mount.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <asm/byteorder.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <mtd/mtd-user.h>
> +#include <glob.h>
> +
> +#include "libfstools.h"
> +
> +#include "volume.h"
> +
> +#define ext4_sysfs_path "/sys/block/mmcblk*/mmcblk*/uevent"
> +#define MAX_SIZE 128
> +
> +#define EXT_SB_OFF 0x400
> +#define EXT_SB_KBOFF (EXT_SB_OFF >> 10)
> +#define EXT_SB_MAGIC "\123\357"
> +#define EXT_MAG_OFF 0x38
> +
> +struct ext4_priv {
> + char *name;
> + char *devname;
> +};
> +
> +static struct driver ext4_driver;
> +
> +static int ext4_volume_init(struct volume *v)
> +{
> + char buf[MAX_SIZE];
> + struct ext4_priv *p;
> +
> + p = (struct ext4_priv*)v->priv;
> + snprintf(buf, sizeof(buf), "/dev/%s",p->devname);
> +
> + v->name = strdup(p->name);
> + v->type = 5;
> + v->blk = strdup(buf);
> + return 0;
> +}
> +
> +static int
> +ext4_part_match(char *dev, char *name, char *filename)
> +{
> + FILE *fp;
> + char buf[MAX_SIZE];
> + char devname[MAX_SIZE];
> + int i;
> + int ret = -1;
> +
> + fp = fopen(filename, "r");
> + if (!fp)
> + return ret;
> +
> + while(fgets(buf, sizeof(buf), fp)) {
> + if(strstr(buf, "DEVNAME")) {
> + strcpy(devname, buf + strlen("DEVNAME="));
> + continue;
> + }
> + /* Match partition name */
> + if(strstr(buf, name)) {
> + ret = 0;
> + break;
> + }
> + }
> +
> + fclose(fp);
> +
> + /* make sure the string is \0 terminated */
> + devname[sizeof(devname) - 1] = '\0';
> +
> + /* remove trailing whitespace */
> + i = strlen(devname) - 1;
> + while (i > 0 && devname[i] <= ' ')
> + devname[i--] = '\0';
> +
> + strcpy(dev, devname);
> + return ret;
> +}
> +
> +static int ext4_find_devname(char *dev, char *name)
> +{
> + int i;
> + glob_t gl;
> +
> + if (glob(ext4_sysfs_path, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl) < 0)
> + return -1;
> +
> + for (i = 0; i < gl.gl_pathc; i++) {
> + if(!ext4_part_match(dev, name, gl.gl_pathv[i])) {
> + globfree(&gl);
> + return 0;
> + }
> + }
> +
> + globfree(&gl);
> + return -1;
> +}
> +
> +static int check_for_mtd(const char *mtd)
> +{
> + FILE *fp;
> + char dev[MAX_SIZE];
> +
> + if ((fp = fopen("/proc/mtd", "r"))) {
> + while (fgets(dev, sizeof(dev), fp)) {
> + if (strstr(dev, mtd)) {
> + fclose(fp);
> + return -1;
> + }
> + }
> + }
> + fclose(fp);
> + return 0;
> +}
> +
> +static int ext4_volume_find(struct volume *v, char *name)
> +{
> + char buf[MAX_SIZE];
> + struct ext4_priv *p;
> +
> + if (find_filesystem("ext4"))
> + return -1;
> +
> + if (check_for_mtd(name))
> + return -1;
> +
> + if(ext4_find_devname(buf,name))
^ missing space
> + return -1;
> +
> + p = calloc(1, sizeof(struct ext4_priv));
> + if (!p)
> + return -1;
> +
> + v->priv = p;
> + v->drv = &ext4_driver;
> +
> + p->devname = strdup(buf);
> + p->name = strdup(name);
> + return ext4_volume_init(v);
> +}
> +
> +static int ext4_volume_identify(struct volume *v)
> +{
> + char magic[32] = { 0 };
> + int off = (EXT_SB_KBOFF * 1024) + EXT_MAG_OFF;
> + int fd;
> +
> + fd = open(v->blk, O_RDONLY);
> + if(fd == -1)
^ missing space
> + return -1;
> +
> + lseek(fd, off, SEEK_SET);
> + read(fd, magic, sizeof(EXT_SB_MAGIC) - 1);
> + close(fd);
> +
> + if (!memcmp(EXT_SB_MAGIC, magic, sizeof(EXT_SB_MAGIC) - 1)) {
> + return FS_EXT4FS;
> + }
> +
> + fprintf(stderr, "ext4 is not ready - marker found\n");
> + return FS_DEADCODE;
> +}
> +
> +static struct driver ext4_driver = {
> + .name = "ext4",
> + .find = ext4_volume_find,
> + .init = ext4_volume_init,
> + .identify = ext4_volume_identify,
> +};
> +
> +DRIVER(ext4_driver);
> diff --git a/libfstools/find.c b/libfstools/find.c
> index 0440052..9fd83c9 100644
> --- a/libfstools/find.c
> +++ b/libfstools/find.c
> @@ -102,7 +102,8 @@ find_mount_point(char *block, int mtd_only)
>
> if (mtd_only &&
> strncmp(t, "jffs2", 5) &&
> - strncmp(t, "ubifs", 5)) {
> + strncmp(t, "ubifs", 5) &&
> + strncmp(t, "ext4", 4)) {
> fclose(fp);
> ULOG_ERR("block is mounted with wrong fs\n");
> return NULL;
> diff --git a/libfstools/libfstools.h b/libfstools/libfstools.h
> index 31d9f9e..940c504 100644
> --- a/libfstools/libfstools.h
> +++ b/libfstools/libfstools.h
> @@ -26,6 +26,7 @@ enum {
> FS_JFFS2,
> FS_DEADCODE,
> FS_UBIFS,
> + FS_EXT4FS,
> };
>
> enum fs_state {
> diff --git a/libfstools/overlay.c b/libfstools/overlay.c
> index cdac23e..773951b 100644
> --- a/libfstools/overlay.c
> +++ b/libfstools/overlay.c
> @@ -101,7 +101,7 @@ overlay_delete(const char *dir, bool _keep_sysupgrade)
> static int
> overlay_mount(struct volume *v, char *fs)
> {
> - if (mkdir("/tmp/overlay", 0755)) {
> + if (mkdir("/tmp/overlay", 0755) && errno != EEXIST) {
> ULOG_ERR("failed to mkdir /tmp/overlay: %s\n", strerror(errno));
> return -1;
> }
this bit should really be in a separate patch as it is not directly
related to the ext4 support
> @@ -196,6 +196,7 @@ int
> jffs2_switch(struct volume *v)
> {
> char *mp;
> + char buf[32];
> int ret = -1;
>
> if (find_overlay_mount("overlayfs:/tmp/root"))
> @@ -212,6 +213,11 @@ jffs2_switch(struct volume *v)
> return -1;
> }
>
> + if(!strcmp((char *)(v->drv->name),"ext4")) {
> + snprintf(buf,sizeof(buf),"mkfs.ext4 %s",v->blk);
several missing spaces in the line above
> + system(buf);
> + }
> +
do we always want to create the FS ? and what is mkfs.ext4 does not exist ?
John
> switch (volume_identify(v)) {
> case FS_NONE:
> ULOG_ERR("no jffs2 marker found\n");
> @@ -245,6 +251,16 @@ jffs2_switch(struct volume *v)
> ret = -1;
> }
> break;
> +
> + case FS_EXT4FS:
> + ret = overlay_mount(v, "ext4");
> + if (ret)
> + break;
> + if (mount_move("/tmp", "", "/overlay") || fopivot("/overlay", "/rom")) {
> + ULOG_ERR("switching to ext4fs failed\n");
> + ret = -1;
> + }
> + break;
> }
>
> if (ret)
> @@ -270,6 +286,10 @@ static int overlay_mount_fs(struct volume *v)
> case FS_UBIFS:
> fstype = "ubifs";
> break;
> +
> + case FS_EXT4FS:
> + fstype = "ext4";
> + break;
> }
>
> volume_init(v);
> diff --git a/mount_root.c b/mount_root.c
> index bf70265..1335f2b 100644
> --- a/mount_root.c
> +++ b/mount_root.c
> @@ -68,6 +68,7 @@ start(int argc, char *argv[1])
>
> case FS_JFFS2:
> case FS_UBIFS:
> + case FS_EXT4FS:
> mount_overlay(data);
> break;
>
>
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list