[LEDE-DEV] [PATCH] fstools: use ramoverlay if no rootfs_data and rootfs is ro

John Crispin john at phrozen.org
Fri Apr 27 09:50:49 PDT 2018



On 27/04/18 14:05, Arvid E. Picciani wrote:
> - libfstools/mtd.c no longer fails if volume is ro.
> - mount_root ramoverlay if no rootfs_data and rootfs is ro

Hi,
this approach is an ugly hack. please do the following

mtd_ope() should always try to open as r/w and if that fails try ro. 
then store that state inside the context.
mtd_volume_load() shoiuld then get an extra param called rw, which 
checks, if set, if the ctx also has rw set. if not return an error. that 
way there is no need for ultra cumbersome reopen logic.

and please do use the ML and dont send patches directly. they wont be 
picked up by patchwork and will bitrot in my mailbox.

     John
> Signed-off-by: Arvid E. Picciani <aep at exys.org>
> ---
>   libfstools/mtd.c    | 35 ++++++++++++++++++++++-------------
>   libfstools/volume.c | 24 ++++++++++++++++++++++++
>   libfstools/volume.h |  1 +
>   mount_root.c        | 11 +++++++++++
>   4 files changed, 58 insertions(+), 13 deletions(-)
>
> diff --git a/libfstools/mtd.c b/libfstools/mtd.c
> index 77c71ee..4ff10ca 100644
> --- a/libfstools/mtd.c
> +++ b/libfstools/mtd.c
> @@ -20,6 +20,7 @@
>   #include <stdio.h>
>   #include <stdlib.h>
>   #include <mtd/mtd-user.h>
> +#include <stdint.h>
>   
>   #include "libfstools.h"
>   
> @@ -32,15 +33,18 @@ struct mtd_volume {
>   	int	fd;
>   	int	idx;
>   	char	*chr;
> +	int	is_writable;
>   };
>   
>   static struct driver mtd_driver;
>   
> -static int mtd_open(const char *mtd, int block)
> +static int mtd_open(const char *mtd, int block, int open_writable)
>   {
>   	FILE *fp;
>   	char dev[PATH_MAX];
> -	int i, ret, flags = O_RDWR | O_SYNC;
> +	int i, ret, flags = O_SYNC;
> +	if (open_writable)
> +		flags |= O_RDWR;
>   
>   	if ((fp = fopen("/proc/mtd", "r"))) {
>   		while (fgets(dev, sizeof(dev), fp)) {
> @@ -70,24 +74,29 @@ static void mtd_volume_close(struct mtd_volume *p)
>   	p->fd = 0;
>   }
>   
> -static int mtd_volume_load(struct mtd_volume *p)
> +static int mtd_volume_load(struct mtd_volume *p,  int open_writable)
>   {
>   	struct volume *v = &p->v;
>   	struct mtd_info_user mtdInfo;
>   	struct erase_info_user mtdLockInfo;
>   
>   	if (p->fd) {
> -		lseek(p->fd, 0, SEEK_SET);
> -		return 0;
> +		if (!open_writable || p->is_writable) {
> +			lseek(p->fd, 0, SEEK_SET);
> +			return 0;
> +		} else {
> +			close(p->fd);
> +			p->fd = 0;
> +		}
>   	}
>   
>   	if (!p->chr)
>   		return -1;
>   
> -	p->fd = mtd_open(p->chr, 0);
> +	p->fd = mtd_open(p->chr, 0, open_writable);
>   	if (p->fd < 0) {
>   		p->fd = 0;
> -		ULOG_ERR("Could not open mtd device: %s\n", p->chr);
> +		ULOG_ERR("Could not open mtd device%s: %s\n", open_writable ? " writable": "", p->chr);
>   		return -1;
>   	}
>   
> @@ -174,7 +183,7 @@ static struct volume *mtd_volume_find(char *name)
>   	snprintf(buffer, sizeof(buffer), "/dev/mtd%s", idx);
>   	p->chr = strdup(buffer);
>   
> -	if (mtd_volume_load(p)) {
> +	if (mtd_volume_load(p, 0)) {
>   		ULOG_ERR("reading %s failed\n", v->name);
>   		free(p);
>   		return NULL;
> @@ -190,7 +199,7 @@ static int mtd_volume_identify(struct volume *v)
>   	__u16 jffs2;
>   	size_t sz;
>   
> -	if (mtd_volume_load(p)) {
> +	if (mtd_volume_load(p, 0)) {
>   		ULOG_ERR("reading %s failed\n", v->name);
>   		return -1;
>   	}
> @@ -228,7 +237,7 @@ static int mtd_volume_erase(struct volume *v, int offset, int len)
>   	struct erase_info_user eiu;
>   	int first_block, num_blocks;
>   
> -	if (mtd_volume_load(p))
> +	if (mtd_volume_load(p, 1))
>   		return -1;
>   
>   	if (offset % v->block_size || len % v->block_size) {
> @@ -270,7 +279,7 @@ static int mtd_volume_init(struct volume *v)
>   	struct mtd_info_user mtdinfo;
>   	int ret;
>   
> -	if (mtd_volume_load(p))
> +	if (mtd_volume_load(p, 0))
>   		return -1;
>   
>   	ret = ioctl(p->fd, MEMGETINFO, &mtdinfo);
> @@ -291,7 +300,7 @@ static int mtd_volume_read(struct volume *v, void *buf, int offset, int length)
>   {
>   	struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
>   
> -	if (mtd_volume_load(p))
> +	if (mtd_volume_load(p, 0))
>   		return -1;
>   
>   	if (lseek(p->fd, offset, SEEK_SET) == (off_t) -1) {
> @@ -311,7 +320,7 @@ static int mtd_volume_write(struct volume *v, void *buf, int offset, int length)
>   {
>   	struct mtd_volume *p = container_of(v, struct mtd_volume, v);;
>   
> -	if (mtd_volume_load(p))
> +	if (mtd_volume_load(p, 1))
>   		return -1;
>   
>   	if (lseek(p->fd, offset, SEEK_SET) == (off_t) -1) {
> diff --git a/libfstools/volume.c b/libfstools/volume.c
> index 0d293d5..9b8a6af 100644
> --- a/libfstools/volume.c
> +++ b/libfstools/volume.c
> @@ -14,6 +14,10 @@
>   #include <sys/mount.h>
>   #include <stdio.h>
>   #include <stdlib.h>
> +#include <stdbool.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <stropts.h>
>   
>   #include "libfstools.h"
>   #include "volume.h"
> @@ -41,3 +45,23 @@ struct volume* volume_find(char *name)
>   
>   	return NULL;
>   }
> +
> +int
> +volume_is_ro(struct volume *v)
> +{
> +	if (!v || !v->blk)
> +		return 0;
> +
> +	int flag = 0;
> +	int fd = open(v->blk, O_RDONLY);
> +
> +	if (fd < 0)
> +		return 0;
> +
> +	if (ioctl (fd, BLKROGET, &flag) == -1)
> +		flag = 0;
> +
> +	close(fd);
> +	return flag;
> +}
> +
> diff --git a/libfstools/volume.h b/libfstools/volume.h
> index 912b711..6460dad 100644
> --- a/libfstools/volume.h
> +++ b/libfstools/volume.h
> @@ -62,6 +62,7 @@ struct volume {
>   
>   extern struct volume* volume_find(char *name);
>   extern void volume_register_driver(struct driver *drv);
> +extern int volume_is_ro(struct volume *v);
>   
>   static inline int volume_init(struct volume *v)
>   {
> diff --git a/mount_root.c b/mount_root.c
> index dffb0a6..6dccf24 100644
> --- a/mount_root.c
> +++ b/mount_root.c
> @@ -33,6 +33,7 @@ start(int argc, char *argv[1])
>   	struct volume *root;
>   	struct volume *data = volume_find("rootfs_data");
>   	struct stat s;
> +	int overlay_from_ramfs = 0;
>   
>   	if (!getenv("PREINIT") && stat("/tmp/.preinit", &s))
>   		return -1;
> @@ -42,6 +43,11 @@ start(int argc, char *argv[1])
>   		volume_init(root);
>   		ULOG_NOTE("mounting /dev/root\n");
>   		mount("/dev/root", "/", NULL, MS_NOATIME | MS_REMOUNT, 0);
> +
> +		// if root is read only and there's no roofs_data, get an overlay from either extroot or ramfs
> +		if (volume_is_ro(root)) {
> +			overlay_from_ramfs = 1;
> +		}
>   	}
>   
>   	/*
> @@ -55,6 +61,11 @@ start(int argc, char *argv[1])
>   		return 0;
>   	}
>   
> +	if (overlay_from_ramfs) {
> +		ULOG_WARN("no rootfs_data and rootfs is read only, using tmpfs overlay\n");
> +		return ramoverlay();
> +	}
> +
>   	/* There isn't extroot, so just try to mount "rootfs_data" */
>   	volume_init(data);
>   	switch (volume_identify(data)) {




More information about the Lede-dev mailing list