[syslinux] [PATCH 1/8] extlinux/main.c: support unmounted ext2/3/4 filesystem
Robert Yang
liezhi.yang at windriver.com
Wed Dec 24 00:16:08 PST 2014
Add install_file_to_device() to support unmounted ext2, ext3 and ext4
filesystem.
Usage:
$ extlinux -i /dev/sdXN
or
$ extlinux -i file_block
We don't need any new options, it will check whether the target is a
directory or device and decide what to do, it would stop and error if
the device is mounted.
More info:
* It will use libext2fs to read and write the file.
* It will be used when the target is a extX device or file block, and
work as before when the target is a directory.
* It will be used for both modifing the existing adv when
update_only == -1, and install the files to the filesystem.
Signed-off-by: Robert Yang <liezhi.yang at windriver.com>
---
extlinux/Makefile | 2 +-
extlinux/main.c | 96 ++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 67 insertions(+), 31 deletions(-)
diff --git a/extlinux/Makefile b/extlinux/Makefile
index 02d1db5..f7035c7 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -52,7 +52,7 @@ spotless: clean
installer: extlinux
extlinux: $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $^
+ $(CC) $(LDFLAGS) -o $@ $^ -lext2fs
strip:
$(STRIP) extlinux
diff --git a/extlinux/main.c b/extlinux/main.c
index 09740bd..9132ce5 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/vfs.h>
+#include <ext2fs/ext2fs.h>
#include "linuxioctl.h"
@@ -991,6 +992,12 @@ static int install_file(const char *path, int devfd, struct stat *rst)
return 1;
}
+
+static int install_file_to_device(const char *device_path, int devfd,
+ int update_only)
+{
+}
+
#ifdef __KLIBC__
static char devname_buf[64];
@@ -1452,15 +1459,26 @@ static int ext_write_adv(const char *path, const char *cfg, int devfd)
return write_adv(path, cfg);
}
-static int install_loader(const char *path, int update_only)
+static int install_loader(const char *path, int update_only, struct stat st)
{
- struct stat st, fst;
+ struct stat fst;
int devfd, rv;
const char *devname;
- devfd = open_device(path, &st, &devname);
- if (devfd < 0)
- return 1;
+ /* Support dir, ext2, ext3 and ext4 filesystem (device or file block) */
+ if S_ISDIR(st.st_mode) {
+ devfd = open_device(path, &st, &devname);
+ if (devfd < 0)
+ return 1;
+ } else if (S_ISBLK(st.st_mode) || S_ISREG(st.st_mode)) {
+ if ((devfd = open(path, O_RDWR | O_SYNC)) < 0) {
+ fprintf(stderr, "%s: cannot open device %s\n", program, devname);
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "%s: unsupported file type: %s\n", program, path);
+ return -1;
+ }
if (update_only && !syslinux_already_installed(devfd)) {
fprintf(stderr, "%s: no previous syslinux boot sector found\n",
@@ -1469,29 +1487,38 @@ static int install_loader(const char *path, int update_only)
return 1;
}
- /* Read a pre-existing ADV, if already installed */
- if (opt.reset_adv) {
- syslinux_reset_adv(syslinux_adv);
- } else if (ext_read_adv(path, devfd, NULL) < 0) {
- close(devfd);
- return 1;
- }
+ if S_ISDIR(st.st_mode) {
+ /* Read a pre-existing ADV, if already installed */
+ if (opt.reset_adv) {
+ syslinux_reset_adv(syslinux_adv);
+ } else if (ext_read_adv(path, devfd, NULL) < 0) {
+ close(devfd);
+ return 1;
+ }
- if (modify_adv() < 0) {
- close(devfd);
- return 1;
- }
+ if (modify_adv() < 0) {
+ close(devfd);
+ return 1;
+ }
- /* Install ldlinux.sys */
- if (install_file(path, devfd, &fst)) {
- close(devfd);
- return 1;
- }
- if (fst.st_dev != st.st_dev) {
- fprintf(stderr, "%s: file system changed under us - aborting!\n",
- program);
- close(devfd);
- return 1;
+ /* Install ldlinux.sys */
+ if (install_file(path, devfd, &fst)) {
+ close(devfd);
+ return 1;
+ }
+ if (fst.st_dev != st.st_dev) {
+ fprintf(stderr, "%s: file system changed under us - aborting!\n",
+ program);
+ close(devfd);
+ return 1;
+ }
+ } else {
+ if (install_file_to_device(path, devfd, update_only)) {
+ fprintf(stderr, "%s: install file to device error!\n", program);
+ close(devfd);
+ return 1;
+ }
+ fs_type = EXT2;
}
sync();
@@ -1533,16 +1560,25 @@ int modify_existing_adv(const char *path)
int main(int argc, char *argv[])
{
parse_options(argc, argv, MODE_EXTLINUX);
+ struct stat st;
if (!opt.directory || opt.install_mbr || opt.activate_partition)
usage(EX_USAGE, 0);
+ if (stat(opt.directory, &st)) {
+ fprintf(stderr, "%s: %s: %s\n", program, opt.directory, strerror(errno));
+ return 1;
+ }
+
if (opt.update_only == -1) {
- if (opt.reset_adv || opt.set_once || opt.menu_save)
- return modify_existing_adv(opt.directory);
- else
+ if (opt.reset_adv || opt.set_once || opt.menu_save) {
+ if S_ISDIR(st.st_mode)
+ return modify_existing_adv(opt.directory);
+ else if (S_ISBLK(st.st_mode) || S_ISREG(st.st_mode))
+ return install_file_to_device(opt.directory, -1, opt.update_only);
+ } else
usage(EX_USAGE, MODE_EXTLINUX);
}
- return install_loader(opt.directory, opt.update_only);
+ return install_loader(opt.directory, opt.update_only, st);
}
--
1.9.1
More information about the Syslinux
mailing list