From ef40780f20635da1ad36b13960521bfa3100949f Mon Sep 17 00:00:00 2001 From: longpanda Date: Sat, 23 May 2020 21:19:26 +0800 Subject: [PATCH] 1.0.11 release --- GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c | 44 +- GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c | 429 ++++++++++++++++++ .../grub-2.04/grub-core/ventoy/ventoy.c | 72 ++- .../grub-2.04/grub-core/ventoy/ventoy_def.h | 13 +- .../grub-2.04/grub-core/ventoy/ventoy_linux.c | 24 +- .../grub-core/ventoy/ventoy_plugin.c | 161 +++++++ GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h | 3 +- IMG/cpio/ventoy/hook/debian/antix-hook.sh | 4 + IMG/cpio/ventoy/hook/debian/default-hook.sh | 3 - IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh | 1 + IMG/cpio/ventoy/hook/ventoy-hook-lib.sh | 53 +++ IMG/cpio/ventoy/ventoy.sh | 5 + INSTALL/Ventoy2Disk.sh | 29 +- INSTALL/grub/grub.cfg | 5 +- License/license-logo.txt | 5 + VtoyTool/vtoydm.c | 9 +- VtoyTool/vtoydump.c | 3 +- 17 files changed, 844 insertions(+), 19 deletions(-) create mode 100644 GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c create mode 100644 License/license-logo.txt diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c index eb0dae5e..8e5b38b0 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/ext2.c @@ -46,6 +46,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -339,7 +340,7 @@ struct grub_ext2_data static grub_dl_t my_mod; - +static int g_ventoy_block_count; /* Check is a = b^x for some x. */ static inline int @@ -499,6 +500,7 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) start = grub_le_to_cpu16 (ext[i].start_hi); start = (start << 32) + grub_le_to_cpu32 (ext[i].start); + g_ventoy_block_count = (int)(grub_le_to_cpu16 (ext[i].len) - fileblock); ret = fileblock + start; } } @@ -1069,8 +1071,46 @@ grub_ext2_mtime (grub_device_t device, grub_int32_t *tm) } +int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list) +{ + int blocksize; + int log2blocksize; + grub_disk_t disk; + grub_disk_addr_t i = 0; + grub_disk_addr_t blockcnt; + grub_disk_addr_t blknr; + grub_fshelp_node_t node = NULL; + + disk = file->device->disk; + node = &(((struct grub_ext2_data *)file->data)->diropen); + + log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data); + blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); + blockcnt = (file->size + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS); + + while (i < blockcnt) + { + g_ventoy_block_count = 1; + blknr = grub_ext2_read_block(node, i); + if (blknr == 0) + { + return 0; + } + + i += g_ventoy_block_count; + blknr = blknr << log2blocksize; + grub_disk_blocklist_read(chunk_list, blknr, g_ventoy_block_count * blocksize, disk->log_sector_size); + } + + for (i = 0; i < chunk_list->cur_chunk; i++) + { + chunk_list->chunk[i].disk_start_sector += part_start; + chunk_list->chunk[i].disk_end_sector += part_start; + } + + return 0; +} - static struct grub_fs grub_ext2_fs = { .name = "ext2", diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c new file mode 100644 index 00000000..5901fac4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c @@ -0,0 +1,429 @@ +/* fshelp.c -- Filesystem helper functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +typedef int (*iterate_dir_func) (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, + void *data); +typedef grub_err_t (*lookup_file_func) (grub_fshelp_node_t dir, + const char *name, + grub_fshelp_node_t *foundnode, + enum grub_fshelp_filetype *foundtype); +typedef char *(*read_symlink_func) (grub_fshelp_node_t node); + +struct stack_element { + struct stack_element *parent; + grub_fshelp_node_t node; + enum grub_fshelp_filetype type; +}; + +/* Context for grub_fshelp_find_file. */ +struct grub_fshelp_find_file_ctx +{ + /* Inputs. */ + const char *path; + grub_fshelp_node_t rootnode; + + /* Global options. */ + int symlinknest; + + /* Current file being traversed and its parents. */ + struct stack_element *currnode; +}; + +/* Helper for find_file_iter. */ +static void +free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx) +{ + if (node != ctx->rootnode) + grub_free (node); +} + +static void +pop_element (struct grub_fshelp_find_file_ctx *ctx) +{ + struct stack_element *el; + el = ctx->currnode; + ctx->currnode = el->parent; + free_node (el->node, ctx); + grub_free (el); +} + +static void +free_stack (struct grub_fshelp_find_file_ctx *ctx) +{ + while (ctx->currnode) + pop_element (ctx); +} + +static void +go_up_a_level (struct grub_fshelp_find_file_ctx *ctx) +{ + if (!ctx->currnode->parent) + return; + pop_element (ctx); +} + +static grub_err_t +push_node (struct grub_fshelp_find_file_ctx *ctx, grub_fshelp_node_t node, enum grub_fshelp_filetype filetype) +{ + struct stack_element *nst; + nst = grub_malloc (sizeof (*nst)); + if (!nst) + return grub_errno; + nst->node = node; + nst->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; + nst->parent = ctx->currnode; + ctx->currnode = nst; + return GRUB_ERR_NONE; +} + +static grub_err_t +go_to_root (struct grub_fshelp_find_file_ctx *ctx) +{ + free_stack (ctx); + return push_node (ctx, ctx->rootnode, GRUB_FSHELP_DIR); +} + +struct grub_fshelp_find_file_iter_ctx +{ + const char *name; + grub_fshelp_node_t *foundnode; + enum grub_fshelp_filetype *foundtype; +}; + +/* Helper for grub_fshelp_find_file. */ +static int +find_file_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_fshelp_find_file_iter_ctx *ctx = data; + + if (filetype == GRUB_FSHELP_UNKNOWN || + ((filetype & GRUB_FSHELP_CASE_INSENSITIVE) + ? grub_strcasecmp (ctx->name, filename) + : grub_strcmp (ctx->name, filename))) + { + grub_free (node); + return 0; + } + + /* The node is found, stop iterating over the nodes. */ + *ctx->foundnode = node; + *ctx->foundtype = filetype; + return 1; +} + +static grub_err_t +directory_find_file (grub_fshelp_node_t node, const char *name, grub_fshelp_node_t *foundnode, + enum grub_fshelp_filetype *foundtype, iterate_dir_func iterate_dir) +{ + int found; + struct grub_fshelp_find_file_iter_ctx ctx = { + .foundnode = foundnode, + .foundtype = foundtype, + .name = name + }; + found = iterate_dir (node, find_file_iter, &ctx); + if (! found) + { + if (grub_errno) + return grub_errno; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +find_file (char *currpath, + iterate_dir_func iterate_dir, lookup_file_func lookup_file, + read_symlink_func read_symlink, + struct grub_fshelp_find_file_ctx *ctx) +{ + char *name, *next; + grub_err_t err; + for (name = currpath; ; name = next) + { + char c; + grub_fshelp_node_t foundnode = NULL; + enum grub_fshelp_filetype foundtype = 0; + + /* Remove all leading slashes. */ + while (*name == '/') + name++; + + /* Found the node! */ + if (! *name) + return 0; + + /* Extract the actual part from the pathname. */ + for (next = name; *next && *next != '/'; next++); + + /* At this point it is expected that the current node is a + directory, check if this is true. */ + if (ctx->currnode->type != GRUB_FSHELP_DIR) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + + /* Don't rely on fs providing actual . in the listing. */ + if (next - name == 1 && name[0] == '.') + continue; + + /* Don't rely on fs providing actual .. in the listing. */ + if (next - name == 2 && name[0] == '.' && name[1] == '.') + { + go_up_a_level (ctx); + continue; + } + + /* Iterate over the directory. */ + c = *next; + *next = '\0'; + if (lookup_file) + err = lookup_file (ctx->currnode->node, name, &foundnode, &foundtype); + else + err = directory_find_file (ctx->currnode->node, name, &foundnode, &foundtype, iterate_dir); + *next = c; + + if (err) + return err; + + if (!foundnode) + break; + + push_node (ctx, foundnode, foundtype); + + /* Read in the symlink and follow it. */ + if (ctx->currnode->type == GRUB_FSHELP_SYMLINK) + { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++ctx->symlinknest == 8) + return grub_error (GRUB_ERR_SYMLINK_LOOP, + N_("too deep nesting of symlinks")); + + symlink = read_symlink (ctx->currnode->node); + + if (!symlink) + return grub_errno; + + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') + { + err = go_to_root (ctx); + if (err) + return err; + } + else + { + /* Get from symlink to containing directory. */ + go_up_a_level (ctx); + } + + + /* Lookup the node the symlink points to. */ + find_file (symlink, iterate_dir, lookup_file, read_symlink, ctx); + grub_free (symlink); + + if (grub_errno) + return grub_errno; + } + } + + return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), + ctx->path); +} + +static grub_err_t +grub_fshelp_find_file_real (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + iterate_dir_func iterate_dir, + lookup_file_func lookup_file, + read_symlink_func read_symlink, + enum grub_fshelp_filetype expecttype) +{ + struct grub_fshelp_find_file_ctx ctx = { + .path = path, + .rootnode = rootnode, + .symlinknest = 0, + .currnode = 0 + }; + grub_err_t err; + enum grub_fshelp_filetype foundtype; + char *duppath; + + if (!path || path[0] != '/') + { + return grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path); + } + + err = go_to_root (&ctx); + if (err) + return err; + + duppath = grub_strdup (path); + if (!duppath) + return grub_errno; + err = find_file (duppath, iterate_dir, lookup_file, read_symlink, &ctx); + grub_free (duppath); + if (err) + { + free_stack (&ctx); + return err; + } + + *foundnode = ctx.currnode->node; + foundtype = ctx.currnode->type; + /* Avoid the node being freed. */ + ctx.currnode->node = 0; + free_stack (&ctx); + + /* Check if the node that was found was of the expected type. */ + if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); + else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + + return 0; +} + +/* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an + error is generated if the node is not of the expected type. */ +grub_err_t +grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + iterate_dir_func iterate_dir, + read_symlink_func read_symlink, + enum grub_fshelp_filetype expecttype) +{ + return grub_fshelp_find_file_real (path, rootnode, foundnode, + iterate_dir, NULL, + read_symlink, expecttype); + +} + +grub_err_t +grub_fshelp_find_file_lookup (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + lookup_file_func lookup_file, + read_symlink_func read_symlink, + enum grub_fshelp_filetype expecttype) +{ + return grub_fshelp_find_file_real (path, rootnode, foundnode, + NULL, lookup_file, + read_symlink, expecttype); + +} + +/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, + beginning with the block POS. READ_HOOK should be set before + reading a block from the file. READ_HOOK_DATA is passed through as + the DATA argument to READ_HOOK. GET_BLOCK is used to translate + file blocks to disk blocks. The file is FILESIZE bytes big and the + blocks have a size of LOG2BLOCKSIZE (in log2). */ +grub_ssize_t +grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf, + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, + grub_disk_addr_t block), + grub_off_t filesize, int log2blocksize, + grub_disk_addr_t blocks_start) +{ + grub_disk_addr_t i, blockcnt; + int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); + + if (pos > filesize) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("attempt to read past the end of file")); + return -1; + } + + /* Adjust LEN so it we can't read past the end of the file. */ + if (pos + len > filesize) + len = filesize - pos; + + blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS); + + for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++) + { + grub_disk_addr_t blknr; + int blockoff = pos & (blocksize - 1); + int blockend = blocksize; + + int skipfirst = 0; + + blknr = get_block (node, i); + if (grub_errno) + return -1; + + blknr = blknr << log2blocksize; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) & (blocksize - 1); + + /* The last portion is exactly blocksize. */ + if (! blockend) + blockend = blocksize; + } + + /* First block. */ + if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS))) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + /* If the block number is 0 this block is not stored on disk but + is zero filled instead. */ + if (blknr) + { + disk->read_hook = read_hook; + disk->read_hook_data = read_hook_data; + + grub_disk_read (disk, blknr + blocks_start, skipfirst, + blockend, buf); + disk->read_hook = 0; + if (grub_errno) + return -1; + } + else if (read_hook != (grub_disk_read_hook_t)grub_disk_blocklist_read) + grub_memset (buf, 0, blockend); + + buf += blocksize - skipfirst; + } + + return len; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index ce77a8c8..883ca097 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -127,6 +127,10 @@ static int ventoy_get_fs_type(const char *fs) { return ventoy_fs_udf; } + else if (grub_strncmp(fs, "fat", 3) == 0) + { + return ventoy_fs_fat; + } return ventoy_fs_max; } @@ -1288,7 +1292,35 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) return; } -static int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +{ + grub_uint32_t i = 0; + grub_uint64_t total = 0; + ventoy_img_chunk *chunk = NULL; + + for (i = 0; i < chunklist->cur_chunk; i++) + { + chunk = chunklist->chunk + i; + + if (chunk->disk_start_sector <= start) + { + debug("%u disk start invalid %lu\n", i, (ulong)start); + return 1; + } + + total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; + } + + if (total != (file->size / 512)) + { + debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)(file->size / 512)); + return 1; + } + + return 0; +} + +int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) { int fs_type; grub_uint32_t i = 0; @@ -1302,6 +1334,10 @@ static int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunkl { grub_fat_get_file_chunk(start, file, chunklist); } + else if (fs_type == ventoy_fs_ext) + { + grub_ext_get_file_chunk(start, file, chunklist); + } else { file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read; @@ -1336,7 +1372,9 @@ static int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunkl static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) { + int rc; grub_file_t file; + grub_disk_addr_t start; (void)ctxt; (void)argc; @@ -1363,12 +1401,19 @@ static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, ch g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; g_img_chunk_list.cur_chunk = 0; - ventoy_get_block_list(file, &g_img_chunk_list, file->device->disk->partition->start); + start = file->device->disk->partition->start; + ventoy_get_block_list(file, &g_img_chunk_list, start); + + rc = ventoy_check_block_list(file, &g_img_chunk_list, start); grub_file_close(file); + + if (rc) + { + return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n"); + } grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace)); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); } @@ -1481,8 +1526,11 @@ static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int arg chunklist.cur_chunk = 0; ventoy_get_block_list(file, &chunklist, 0); - - grub_file_close(file); + + if (0 != ventoy_check_block_list(file, &chunklist, 0)) + { + grub_printf("########## UNSUPPORTED ###############\n"); + } grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk); @@ -1493,6 +1541,7 @@ static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int arg } grub_printf("\n==================================\n"); + for (i = 0; i < chunklist.cur_chunk; i++) { grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i, @@ -1504,6 +1553,7 @@ static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int arg } grub_free(chunklist.chunk); + grub_file_close(file); VENTOY_CMD_RETURN(GRUB_ERR_NONE); } @@ -1566,6 +1616,17 @@ static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int a return 0; } +static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_persistence(); + + return 0; +} + static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args) { (void)ctxt; @@ -1812,6 +1873,7 @@ static cmd_para ventoy_cmds[] = { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, + { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index c0456236..0202045f 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -561,6 +561,14 @@ typedef struct install_template struct install_template *next; }install_template; +typedef struct persistence_config +{ + char isopath[256]; + char filepath[256]; + + struct persistence_config *next; +}persistence_config; + extern int g_ventoy_last_entry; extern int g_ventoy_memdisk_mode; extern int g_ventoy_iso_raw; @@ -571,7 +579,10 @@ void ventoy_swap_img(img_info *img1, img_info *img2); char * ventoy_plugin_get_install_template(const char *isopath); void ventoy_plugin_dump_auto_install(void); int ventoy_fill_windows_rtdata(void *buf, char *isopath); - +int ventoy_plugin_get_persistent_chunklist(const char *isopath, ventoy_img_chunk_list *chunk_list); +int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); +int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); +void ventoy_plugin_dump_persistence(void); #endif /* __VENTOY_DEF_H__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c index 06cd046e..403bf30b 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c @@ -852,8 +852,10 @@ grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args) { + int rc; char *template_file = NULL; char *template_buf = NULL; + char *persistent_buf = NULL; grub_uint8_t *buf = NULL; grub_uint32_t mod; grub_uint32_t headlen; @@ -861,9 +863,11 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg grub_uint32_t padlen; grub_uint32_t img_chunk_size; grub_uint32_t template_size = 0; + grub_uint32_t persistent_size = 0; grub_file_t file; grub_file_t scriptfile; - + ventoy_img_chunk_list chunk_list; + (void)ctxt; (void)argc; @@ -892,6 +896,13 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg g_ventoy_cpio_size = 0; } + rc = ventoy_plugin_get_persistent_chunklist(args[1], &chunk_list); + if (rc == 0 && chunk_list.cur_chunk > 0 && chunk_list.chunk) + { + persistent_size = chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + persistent_buf = (char *)(chunk_list.chunk); + } + template_file = ventoy_plugin_get_install_template(args[1]); if (template_file) { @@ -915,7 +926,7 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg } } - g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + img_chunk_size); + g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + img_chunk_size); if (NULL == g_ventoy_cpio_buf) { grub_file_close(file); @@ -943,6 +954,15 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg buf += headlen + ventoy_align(template_size, 4); } + if (persistent_size > 0 && persistent_buf) + { + headlen = ventoy_cpio_newc_fill_head(buf, persistent_size, persistent_buf, "ventoy/ventoy_persistent_map"); + buf += headlen + ventoy_align(persistent_size, 4); + + grub_free(persistent_buf); + persistent_buf = NULL; + } + /* step2: insert os param to cpio */ headlen = ventoy_cpio_newc_fill_head(buf, 0, NULL, "ventoy/ventoy_os_param"); padlen = sizeof(ventoy_os_param); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c index 82de5130..16a31cc3 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c @@ -38,7 +38,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); +static char g_iso_disk_name[128]; static install_template *g_install_template_head = NULL; +static persistence_config *g_persistence_head = NULL; static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk) { @@ -101,6 +103,24 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) debug("vtoy_gfxmode %s\n", value); grub_env_set("vtoy_gfxmode", value); } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); + if (value) + { + grub_env_set("VTLE_LFT", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top"); + if (value) + { + grub_env_set("VTLE_TOP", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color"); + if (value) + { + grub_env_set("VTLE_CLR", value); + } return 0; } @@ -162,11 +182,68 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk } +static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) +{ + const char *iso = NULL; + const char *persist = NULL; + VTOY_JSON *pNode = NULL; + persistence_config *node = NULL; + persistence_config *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_persistence_head) + { + for (node = g_persistence_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_persistence_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso && iso[0] == '/') + { + persist = vtoy_json_get_string_ex(pNode->pstChild, "backend"); + if (persist && persist[0] == '/') + { + node = grub_zalloc(sizeof(persistence_config)); + if (node) + { + grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + grub_snprintf(node->filepath, sizeof(node->filepath), "%s", persist); + + if (g_persistence_head) + { + node->next = g_persistence_head; + } + + g_persistence_head = node; + } + } + } + } + + return 0; +} + + static plugin_entry g_plugin_entries[] = { { "control", ventoy_plugin_control_entry }, { "theme", ventoy_plugin_theme_entry }, { "auto_install", ventoy_plugin_auto_install_entry }, + { "persistence", ventoy_plugin_persistence_entry }, }; static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) @@ -174,6 +251,8 @@ static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) int i; VTOY_JSON *cur = json; + grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk); + while (cur) { for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++) @@ -260,6 +339,32 @@ void ventoy_plugin_dump_auto_install(void) return; } +void ventoy_plugin_dump_persistence(void) +{ + int rc; + persistence_config *node = NULL; + ventoy_img_chunk_list chunk_list; + + for (node = g_persistence_head; node; node = node->next) + { + grub_printf("IMAGE:<%s>\n", node->isopath); + grub_printf("PERSIST:<%s>", node->filepath); + + rc = ventoy_plugin_get_persistent_chunklist(node->isopath, &chunk_list); + if (rc == 0) + { + grub_printf(" [ SUCCESS ]\n\n"); + grub_free(chunk_list.chunk); + } + else + { + grub_printf(" [ FAILED ]\n\n"); + } + } + + return; +} + char * ventoy_plugin_get_install_template(const char *isopath) { @@ -276,3 +381,59 @@ char * ventoy_plugin_get_install_template(const char *isopath) return NULL; } +int ventoy_plugin_get_persistent_chunklist(const char *isopath, ventoy_img_chunk_list *chunk_list) +{ + int rc = 1; + grub_uint64_t start = 0; + grub_file_t file = NULL; + persistence_config *node = NULL; + + for (node = g_persistence_head; node; node = node->next) + { + if (grub_strcmp(node->isopath, isopath) == 0) + { + break; + } + } + + if (NULL == node) + { + goto end; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->filepath); + if (!file) + { + debug("Failed to open file %s%s\n", g_iso_disk_name, node->filepath); + goto end; + } + + grub_memset(chunk_list, 0, sizeof(ventoy_img_chunk_list)); + chunk_list->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == chunk_list->chunk) + { + goto end; + } + + chunk_list->max_chunk = DEFAULT_CHUNK_NUM; + chunk_list->cur_chunk = 0; + + start = file->device->disk->partition->start; + ventoy_get_block_list(file, chunk_list, start); + + if (0 != ventoy_check_block_list(file, chunk_list, start)) + { + grub_free(chunk_list->chunk); + chunk_list->chunk = NULL; + goto end; + } + + rc = 0; + +end: + if (file) + grub_file_close(file); + + return rc; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h index 205ba1d1..799bfb4e 100644 --- a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h @@ -35,6 +35,7 @@ typedef enum ventoy_fs_type ventoy_fs_ext, /* 2: ext2/ext3/ext4 */ ventoy_fs_xfs, /* 3: XFS */ ventoy_fs_udf, /* 4: UDF */ + ventoy_fs_fat, /* 5: FAT */ ventoy_fs_max }ventoy_fs_type; @@ -224,7 +225,7 @@ typedef struct ventoy_grub_param #pragma pack() - +int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file); grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file); diff --git a/IMG/cpio/ventoy/hook/debian/antix-hook.sh b/IMG/cpio/ventoy/hook/debian/antix-hook.sh index 66615047..fa9d0834 100644 --- a/IMG/cpio/ventoy/hook/debian/antix-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/antix-hook.sh @@ -25,5 +25,9 @@ fi $SED -i "/_search_for_boot_device_/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/antix-disk.sh" /init +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + $SED 's#for param in $cmdline#for param in persist_all $cmdline#g' -i /init +fi + # for debug #$SED -i "/^linuxfs_error/a\exec $VTOY_PATH/busybox/sh" /init diff --git a/IMG/cpio/ventoy/hook/debian/default-hook.sh b/IMG/cpio/ventoy/hook/debian/default-hook.sh index 706173b2..bd2dd1ea 100644 --- a/IMG/cpio/ventoy/hook/debian/default-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/default-hook.sh @@ -50,6 +50,3 @@ if [ -f $VTOY_PATH/autoinstall ]; then fi fi - - - diff --git a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh index 6bc7077d..007d2fa3 100644 --- a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh @@ -118,5 +118,6 @@ else fi fi + # OK finish set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh index f70d5574..c656c6fe 100644 --- a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh +++ b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh @@ -215,6 +215,29 @@ create_ventoy_device_mapper() { fi } +create_persistent_device_mapper() { + vtlog "create_persistent_device_mapper $*" + + VT_DM_BIN=$(ventoy_find_bin_path dmsetup) + if [ -z "$VT_DM_BIN" ]; then + vtlog "no dmsetup avaliable, lastly try inbox dmsetup" + VT_DM_BIN=$VTOY_PATH/tool/dmsetup + fi + + vtlog "dmsetup avaliable in system $VT_DM_BIN" + + if ventoy_check_dm_module "$1"; then + vtlog "device-mapper module check success" + else + vterr "Error: no dm module avaliable" + fi + + $VTOY_PATH/tool/vtoydm -p -f $VTOY_PATH/ventoy_persistent_map -d $1 > $VTOY_PATH/persistent_dm_table + $VT_DM_BIN create vtoy_persistent $VTOY_PATH/persistent_dm_table >>$VTLOG 2>&1 +} + + + wait_for_ventoy_dm_disk_label() { DM=$($BUSYBOX_PATH/readlink $VTOY_DM_PATH) vtlog "wait_for_ventoy_dm_disk_label $DM ..." @@ -385,6 +408,30 @@ ventoy_copy_device_mapper() { fi } +# create link for device-mapper +ventoy_create_persistent_link() { + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep vtoy_persistent | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + if ! [ -d /dev/disk/by-label ]; then + mkdir -p /dev/disk/by-label + fi + + VTLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + if [ -z "$VTLABEL" ]; then + VTLABEL=casper-rw + fi + + vtlog "Persistent Label: ##${VTLABEL}##" + + if ! [ -e /dev/disk/by-label/$VTLABEL ]; then + vtOldDir=$PWD + cd /dev/disk/by-label + ln -s ../../$vtDM $VTLABEL + cd $vtOldDir + fi +} + ventoy_udev_disk_common_hook() { VTDISK="${1:0:-1}" @@ -419,8 +466,14 @@ ventoy_udev_disk_common_hook() { else ventoy_copy_device_mapper "/dev/$1" fi + + if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + create_persistent_device_mapper "/dev/$VTDISK" + ventoy_create_persistent_link + fi } + is_inotify_ventoy_part() { if echo $1 | grep -q "2$"; then if ! [ -e /sys/block/$1 ]; then diff --git a/IMG/cpio/ventoy/ventoy.sh b/IMG/cpio/ventoy/ventoy.sh index 5beb46df..e64a4a76 100644 --- a/IMG/cpio/ventoy/ventoy.sh +++ b/IMG/cpio/ventoy/ventoy.sh @@ -222,6 +222,11 @@ if [ "$rmproc" = "Y" ]; then $BUSYBOX_PATH/rm -rf /proc fi +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + export PERSISTENT='YES' + export PERSISTENCE='true' +fi + cd / unset VTOY_PATH VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh index 64322178..01a5ab4c 100644 --- a/INSTALL/Ventoy2Disk.sh +++ b/INSTALL/Ventoy2Disk.sh @@ -111,17 +111,31 @@ if ! check_tool_work_ok; then fi grep "^$DISK" /proc/mounts | while read mtline; do - mtpnt=$(echo $mtline | awk '{print $DISK}') + mtpnt=$(echo $mtline | awk '{print $2}') vtdebug "Trying to umount $mtpnt ..." umount $mtpnt >/dev/null 2>&1 done +if swapon -s | grep -q "^${DISK}[0-9]"; then + swapon -s | grep "^${DISK}[0-9]" | awk '{print $1}' | while read line; do + vtdebug "Trying to swapoff $line ..." + swapoff $line + done +fi + + if grep "$DISK" /proc/mounts; then vterr "$DISK is already mounted, please umount it first!" cd $OLDDIR exit 1 fi +if swapon -s | grep -q "^${DISK}[0-9]"; then + vterr "$DISK is used as swap, please swapoff it first!" + cd $OLDDIR + exit 1 +fi + if [ "$MODE" = "install" ]; then vtdebug "install ventoy ..." @@ -230,6 +244,12 @@ if [ "$MODE" = "install" ]; then vtinfo "esp partition processing ..." + sleep 1 + mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') + if [ -n "$mtpnt" ]; then + umount $mtpnt >/dev/null 2>&1 + fi + if [ "$SECUREBOOT" != "YES" ]; then mkdir ./tmp_mnt @@ -239,9 +259,14 @@ if [ "$MODE" = "install" ]; then vtdebug "mounting part2 success" break fi + + mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') + if [ -n "$mtpnt" ]; then + umount $mtpnt >/dev/null 2>&1 + fi sleep 2 done - + rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index ab18f8d8..0c51f5c1 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -121,6 +121,7 @@ function distro_specify_initrd_file { fi } + function distro_specify_initrd_file_phase2 { if [ -f (loop)/boot/initrd.img ]; then vt_linux_specify_initrd_file /boot/initrd.img @@ -132,6 +133,8 @@ function distro_specify_initrd_file_phase2 { vt_linux_specify_initrd_file /boot/iniramfs.igz elif [ -f (loop)/initrd-x86_64 ]; then vt_linux_specify_initrd_file /initrd-x86_64 + elif [ -f (loop)/live/initrd.img ]; then + vt_linux_specify_initrd_file /live/initrd.img fi } @@ -453,7 +456,7 @@ function common_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.10" +set VENTOY_VERSION="1.0.11" # Default menu display mode, you can change it as you want. # 0: List mode diff --git a/License/license-logo.txt b/License/license-logo.txt new file mode 100644 index 00000000..cfaa8772 --- /dev/null +++ b/License/license-logo.txt @@ -0,0 +1,5 @@ +Ventoy Logo was downloaded from https://www.easyicon.net/29165-usb_icon.html +As descripted in the website: + +Author: Ahmad Hania +License: Creative Commons (Attribution-Noncommercial-Share Alike 3.0 Unported) diff --git a/VtoyTool/vtoydm.c b/VtoyTool/vtoydm.c index d45050c1..aa460af0 100644 --- a/VtoyTool/vtoydm.c +++ b/VtoyTool/vtoydm.c @@ -500,10 +500,17 @@ static int vtoydm_print_linear_table(const char *img_map_file, const char *diskn { sector_start = chunk[i].img_start_sector; sector_num = chunk[i].img_end_sector - chunk[i].img_start_sector + 1; - + + /* TBD: to be more flexible */ + #if 0 printf("%u %u linear %s %llu\n", (sector_start << 2), (sector_num << 2), diskname, (unsigned long long)chunk[i].disk_start_sector); + #else + printf("%u %u linear %s1 %llu\n", + (sector_start << 2), (sector_num << 2), + diskname, (unsigned long long)chunk[i].disk_start_sector - 2048); + #endif } free(chunk); diff --git a/VtoyTool/vtoydump.c b/VtoyTool/vtoydump.c index e494598a..1c620d3c 100644 --- a/VtoyTool/vtoydump.c +++ b/VtoyTool/vtoydump.c @@ -50,6 +50,7 @@ typedef enum ventoy_fs_type ventoy_fs_ext, /* 2: ext2/ext3/ext4 */ ventoy_fs_xfs, /* 3: XFS */ ventoy_fs_udf, /* 4: UDF */ + ventoy_fs_fat, /* 5: FAT */ ventoy_fs_max }ventoy_fs_type; @@ -143,7 +144,7 @@ static ventoy_guid vtoy_guid = VENTOY_GUID; static const char *g_ventoy_fs[ventoy_fs_max] = { - "exfat", "ntfs", "ext*", "xfs", "udf" + "exfat", "ntfs", "ext*", "xfs", "udf", "fat" }; static int vtoy_check_os_param(ventoy_os_param *param)