Created
April 27, 2018 12:44
-
-
Save aep/09eaf088b54c2d3e93d1b3a638e1de99 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fstools: use ramoverlay if no rootfs_data and rootfs is ro | |
- libfstools/mtd.c no longer fails if volume is ro. | |
- mount_root ramoverlay if no rootfs_data and rootfs is ro | |
Signed-off-by: Arvid E. Picciani <[email protected]> | |
--- | |
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)) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment