diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c index 6e40f426..93ad678e 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -5712,6 +5712,7 @@ static cmd_para ventoy_cmds[] = { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver, 0, NULL, "", "", NULL }, { "vt_unix_parse_freebsd_ver_elf", ventoy_cmd_unix_freebsd_ver_elf, 0, NULL, "", "", NULL }, { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, + { "vt_unix_check_vlnk", ventoy_cmd_unix_check_vlnk, 0, NULL, "", "", NULL }, { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, { "vt_unix_replace_grub_conf", ventoy_cmd_unix_replace_grub_conf, 0, NULL, "", "", NULL }, { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 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 763ed179..dfffbe85 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 @@ -1093,6 +1093,7 @@ grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, cha grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature); grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c index dbb30e17..8ff21248 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c @@ -48,6 +48,7 @@ int g_mod_new_len = 0; char *g_mod_new_data = NULL; int g_mod_search_magic = 0; +int g_unix_vlnk_boot = 0; int g_ko_fillmap_len = 0; char *g_ko_fillmap_data = NULL; @@ -280,6 +281,7 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath, const char grub_disk_t disk; grub_file_t isofile; char uuid[64] = {0}; + const char *val = NULL; ventoy_img_chunk *chunk; grub_uint8_t disk_sig[4]; grub_uint8_t disk_guid[16]; @@ -294,17 +296,31 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath, const char vtoy_ssprintf(buf, pos, "ventoy_load=\"%s\"\n", "YES"); vtoy_ssprintf(buf, pos, "ventoy_name=\"%s\"\n", g_ko_mod_path); + if (alias) { vtoy_ssprintf(buf, pos, "hint.ventoy.0.alias=\"%s\"\n", alias); } + if (g_unix_vlnk_boot) + { + vtoy_ssprintf(buf, pos, "hint.ventoy.0.vlnk=%d\n", 1); + } + + val = ventoy_get_env("VTOY_UNIX_REMOUNT"); + if (val && val[0] == '1' && val[1] == 0) + { + vtoy_ssprintf(buf, pos, "hint.ventoy.0.remount=%d\n", 1); + } + if (g_mod_search_magic) { debug("hint.ventoy NO need\n"); goto out; } + debug("Fill hint.ventoy info\n"); + disk = isofile->device->disk; ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig); @@ -353,6 +369,7 @@ grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **ar (void)argc; (void)args; + g_unix_vlnk_boot = 0; g_mod_search_magic = 0; g_conf_new_len = 0; g_mod_new_len = 0; @@ -367,6 +384,27 @@ grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **ar VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +grub_err_t ventoy_cmd_unix_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (file) + { + g_unix_vlnk_boot = file->vlnk; + grub_file_close(file); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args) { grub_file_t file; @@ -653,13 +691,14 @@ out: grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int argc, char **args) { - int len; + int len = 0; grub_uint32_t i; char *data; char *pos; + const char *val = NULL; grub_uint64_t offset; grub_file_t file; - char extcfg[256]; + char extcfg[512]; const char *confile = NULL; const char * loader_conf[] = { @@ -716,18 +755,31 @@ grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int arg if (pos) { pos += grub_strlen("kfreebsd /boot/kernel/kernel"); - + if (grub_strncmp(pos, ".gz", 3) == 0) + { + pos += 3; + } + if (argc == 2) { - len = grub_snprintf(extcfg, sizeof(extcfg), - ";kfreebsd_module_elf %s; set kFreeBSD.hint.ventoy.0.alias=\"%s\"", - args[0], args[1]); + vtoy_ssprintf(extcfg, len, ";kfreebsd_module_elf %s; set kFreeBSD.hint.ventoy.0.alias=\"%s\"", args[0], args[1]); } else { - len = grub_snprintf(extcfg, sizeof(extcfg), ";kfreebsd_module_elf %s", args[0]); + vtoy_ssprintf(extcfg, len, ";kfreebsd_module_elf %s", args[0]); } - + + if (g_unix_vlnk_boot) + { + vtoy_ssprintf(extcfg, len, ";set kFreeBSD.hint.ventoy.0.vlnk=%d", 1); + } + + val = ventoy_get_env("VTOY_UNIX_REMOUNT"); + if (val && val[0] == '1' && val[1] == 0) + { + vtoy_ssprintf(extcfg, len, ";set kFreeBSD.hint.ventoy.0.remount=%d", 1); + } + grub_memmove(pos + len, pos, (int)(file->size - (pos - data))); grub_memcpy(pos, extcfg, len); g_conf_new_len += len; @@ -784,7 +836,7 @@ grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, ch return 1; } - debug("old conf file size:%d\n", (int)file->size); + debug("old conf file <%s> size:%d\n", confile, (int)file->size); data = grub_malloc(VTOY_MAX_SCRIPT_BUF); if (!data) @@ -816,13 +868,13 @@ static int ventoy_unix_search_magic(char *data, int len) int i; grub_uint32_t *magic = NULL; - for (i = 0; i < len; i += 65536) + for (i = 0; i < len; i += 4096) { magic = (grub_uint32_t *)(data + i); if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 && magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3) { - debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 16)); + debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 12)); g_mod_search_magic = i; return 0; } diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index e2998ceb..d0e27f53 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -500,6 +500,8 @@ function ventoy_freebsd_proc { if [ "$vt_freebsd_ver" = "xx" ]; then if [ -e (loop)/boot/kernel/kernel ]; then vt_unix_parse_freebsd_ver_elf (loop)/boot/kernel/kernel $vt_freebsd_bit vt_freebsd_ver + elif [ -e (loop)/boot/kernel/kernel.gz ]; then + vt_unix_parse_freebsd_ver_elf (loop)/boot/kernel/kernel.gz $vt_freebsd_bit vt_freebsd_ver fi if [ "$vt_freebsd_ver" = "xx" ]; then @@ -551,6 +553,8 @@ function ventoy_dragonfly_proc { function ventoy_unix_comm_proc { vt_unix_reset + vt_unix_check_vlnk "${1}${chosen_path}" + if [ "$ventoy_compatible" = "NO" ]; then loopback vtunix $vtoy_efi_part/ventoy/ventoy_unix.cpio diff --git a/INSTALL/ventoy/ventoy_unix.cpio b/INSTALL/ventoy/ventoy_unix.cpio index 22d6af4d..b6136027 100644 Binary files a/INSTALL/ventoy/ventoy_unix.cpio and b/INSTALL/ventoy/ventoy_unix.cpio differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz index e1b5d090..36db9140 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz index 7bfa9793..e044f3cc 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz index 701274e9..ae1ad2b7 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz index 2fce19c3..571bcfcb 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz index 710122b4..1381aac0 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz index ed11c653..647cde82 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz index 27666a9c..412e31c2 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz index 7bbca670..f5d92658 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz index 8963f9ec..ab64fe9b 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz index 49385f60..b8caeafa 100644 Binary files a/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz and b/Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz differ diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c index 332ddd2c..a618140e 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c @@ -65,11 +65,22 @@ static g_taste_t g_ventoy_taste; static g_ctl_req_t g_ventoy_config; static g_dumpconf_t g_ventoy_dumpconf; -static const char *g_ventoy_disk_uuid = NULL; +static char g_ventoy_disk_uuid[64]; static bool g_ventoy_tasted = false; static off_t g_ventoy_disk_size = 0; static off_t g_disk_map_start = 0; static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; + +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = +{ + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, + { 0, 0, 0, 0 }, + 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { { 0, 0 } }, + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 } +}; struct g_class g_ventoy_class = { .name = G_VENTOY_CLASS_NAME, @@ -191,12 +202,19 @@ g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) g_topology_assert(); gp = pp->geom; - /* On first open, grab an extra "exclusive" bit */ - if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) - de++; - /* ... and let go of it on last close */ - if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) - de--; + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { error = g_access(cp1, dr, dw, de); @@ -642,24 +660,52 @@ g_ventoy_destroy_geom(struct gctl_req *req __unused, static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { int i; + int vlnk = 0; + bool ret = true; uint8_t *buf; char uuid[64]; const char *value; struct g_consumer *cp; struct g_geom *gp; + uint8_t mbrdata[] = { + 0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D, + }; if (g_ventoy_disk_size == 0) { - if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - G_DEBUG("ventoy.disksize: %s\n", value); - g_ventoy_disk_size = strtouq(value, NULL, 0); - } + G_DEBUG("ventoy map data is valid. [OK]\n"); - if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) - { + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", g_ventoy_map_data.diskuuid[i]); + } + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", uuid); + g_ventoy_disk_size = g_ventoy_map_data.disksize; + + G_DEBUG("ventoy.disksize: %llu\n", (unsigned long long)g_ventoy_disk_size); G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); } + else + { + G_DEBUG("ventoy map data is invalid, get from resource\n"); + + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &value) == 0) + { + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", value); + G_DEBUG("ventoy.diskuuid: <%s>\n", value); + } + } } if (g_ventoy_disk_size != pp->mediasize) @@ -700,14 +746,28 @@ static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); } - g_free(buf); - - if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + + if (strncmp(g_ventoy_disk_uuid, uuid, 32)) { - return true; + ret = false; } - return false; + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) + { + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } + } + + g_free(buf); + + if (ret) + { + G_DEBUG("ventoy disk check OK\n"); + } + + return ret; } static struct g_geom * @@ -716,8 +776,10 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) int i; int error; int disknum; + int remount = 0; char *endpos; const char *value; + const char *alias = NULL; struct g_geom *gp; struct g_ventoy_metadata md; struct g_ventoy_softc *sc; @@ -741,9 +803,32 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_ventoy_tasted = true; - G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); - resource_int_value("ventoy", 0, "segnum", &disknum); + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + + /* hint.ventoy.0.alias=xxx */ + if (resource_string_value("ventoy", 0, "alias", &alias) == 0 && alias) + { + G_DEBUG("###### ventoy alias <%s> ######\n", alias); + setenv("kern.devalias.ventoy/IMAGE", alias); + } + + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + disknum = (int)g_ventoy_map_data.segnum; + G_DEBUG("segnum from map data is:<%d>\n", disknum); + } + else + { + resource_int_value("ventoy", 0, "segnum", &disknum); + G_DEBUG("segnum from resource is:<%d>\n", disknum); + } strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); md.md_version = G_VENTOY_VERSION; @@ -765,18 +850,29 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) for (i = 0; i < disknum; i ++) { - if (resource_string_value("ventoy", i, "seg", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - g_disk_map_start = strtouq(value, &endpos, 0); - g_disk_map_end = strtouq(endpos + 1, NULL, 0); + G_DEBUG("[map] ventoy segment%d: 0x%llx@0x%llx\n", i, + (long long)g_ventoy_map_data.seglist[i].seg_start_bytes, + (long long)g_ventoy_map_data.seglist[i].seg_end_bytes); + + g_disk_map_start = (off_t)g_ventoy_map_data.seglist[i].seg_start_bytes; + g_disk_map_end = (off_t)g_ventoy_map_data.seglist[i].seg_end_bytes; } else { - printf("Failed to parse ventoy seg %d\n", i); - continue; + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + G_DEBUG("[resource] ventoy segment%d: %s\n", i, value); } - - G_DEBUG("ventoy segment%d: %s\n", i, value); G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); error = g_ventoy_add_disk(sc, pp, i); @@ -792,7 +888,7 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_disk_map_end = 0; } - return (gp); + return (gp); } static void diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h index e442b246..abe565bd 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h @@ -76,6 +76,33 @@ struct g_ventoy_softc { struct mtx sc_lock; }; #define sc_name sc_geom->name + + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + uint64_t seg_start_bytes; + uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + uint32_t magic1[4]; + uint32_t magic2[4]; + uint64_t segnum; + uint64_t disksize; + uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + uint32_t magic3[4]; +}; +#pragma pack() + +#define VENTOY_MAP_VALID(magic2) \ + (magic2[0] == VENTOY_UNIX_SEG_MAGIC0 && magic2[1] == VENTOY_UNIX_SEG_MAGIC1 && magic2[2] == VENTOY_UNIX_SEG_MAGIC2 && magic2[3] == VENTOY_UNIX_SEG_MAGIC3) + #endif /* _KERNEL */ struct g_ventoy_metadata { diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c index 5e8642f7..be9780ee 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c @@ -65,11 +65,22 @@ static g_taste_t g_ventoy_taste; static g_ctl_req_t g_ventoy_config; static g_dumpconf_t g_ventoy_dumpconf; -static const char *g_ventoy_disk_uuid = NULL; +static char g_ventoy_disk_uuid[64]; static bool g_ventoy_tasted = false; static off_t g_ventoy_disk_size = 0; static off_t g_disk_map_start = 0; static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; + +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = +{ + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, + { 0, 0, 0, 0 }, + 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { { 0, 0 } }, + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 } +}; struct g_class g_ventoy_class = { .name = G_VENTOY_CLASS_NAME, @@ -191,12 +202,19 @@ g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) g_topology_assert(); gp = pp->geom; - /* On first open, grab an extra "exclusive" bit */ - if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) - de++; - /* ... and let go of it on last close */ - if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) - de--; + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { error = g_access(cp1, dr, dw, de); @@ -678,24 +696,52 @@ g_ventoy_destroy_geom(struct gctl_req *req __unused, static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { int i; + int vlnk = 0; + bool ret = true; uint8_t *buf; char uuid[64]; const char *value; struct g_consumer *cp; struct g_geom *gp; + uint8_t mbrdata[] = { + 0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D, + }; if (g_ventoy_disk_size == 0) { - if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - G_DEBUG("ventoy.disksize: %s\n", value); - g_ventoy_disk_size = strtouq(value, NULL, 0); - } + G_DEBUG("ventoy map data is valid. [OK]\n"); - if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) - { + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", g_ventoy_map_data.diskuuid[i]); + } + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", uuid); + g_ventoy_disk_size = g_ventoy_map_data.disksize; + + G_DEBUG("ventoy.disksize: %llu\n", (unsigned long long)g_ventoy_disk_size); G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); } + else + { + G_DEBUG("ventoy map data is invalid, get from resource\n"); + + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &value) == 0) + { + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", value); + G_DEBUG("ventoy.diskuuid: <%s>\n", value); + } + } } if (g_ventoy_disk_size != pp->mediasize) @@ -736,14 +782,93 @@ static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); } - g_free(buf); - - if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + + if (strncmp(g_ventoy_disk_uuid, uuid, 32)) { - return true; + ret = false; } - return false; + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) + { + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } + } + + g_free(buf); + + if (ret) + { + G_DEBUG("ventoy disk check OK\n"); + } + + return ret; +} + +struct g_dev_softc { + struct mtx sc_mtx; + struct cdev *sc_dev; + struct cdev *sc_alias; + int sc_open; + int sc_active; +}; + +static int g_ventoy_devalias(struct g_provider *pp) +{ + static int firstflag = 0; + const static char *ventoy_alias = NULL; + static struct g_provider *ventoy_pp = NULL; + struct g_consumer *cp; + struct cdev *adev; + struct g_dev_softc *sc; + + if (firstflag == 0) + { + /* hint.ventoy.0.alias=xxx */ + if (resource_string_value("ventoy", 0, "alias", &ventoy_alias) == 0) + { + G_DEBUG("###### ventoy alias <%s> ######\n", ventoy_alias); + } + else + { + ventoy_alias = NULL; + } + firstflag = 1; + } + + if (!ventoy_alias) + { + return 0; + } + + if (!ventoy_pp) + { + if (strcmp(pp->name, "ventoy/IMAGE") == 0) + { + ventoy_pp = pp; + } + return 0; + } + + LIST_FOREACH(cp, &ventoy_pp->consumers, consumers) { + if (cp->geom && cp->geom->class && cp->geom->class->name) + { + printf("111 cp->geom->class->name=<%s>\n", cp->geom->class->name); + + if (strcmp(cp->geom->class->name, "DEV") == 0) + { + sc = cp->private; + + make_dev_alias_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &adev, sc->sc_dev, "%s", ventoy_alias); + G_DEBUG("Create devalias for ventoy <%s>\n", ventoy_alias); + ventoy_alias = NULL; + break; + } + } + } + + return 0; } static struct g_geom * @@ -752,12 +877,15 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) int i; int error; int disknum; + int remount = 0; char *endpos; const char *value; struct g_geom *gp; struct g_ventoy_metadata md; struct g_ventoy_softc *sc; + g_ventoy_devalias(pp); + if (g_ventoy_tasted) { return NULL; @@ -777,9 +905,25 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_ventoy_tasted = true; - G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); - resource_int_value("ventoy", 0, "segnum", &disknum); + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + disknum = (int)g_ventoy_map_data.segnum; + G_DEBUG("segnum from map data is:<%d>\n", disknum); + } + else + { + resource_int_value("ventoy", 0, "segnum", &disknum); + G_DEBUG("segnum from resource is:<%d>\n", disknum); + } strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); md.md_version = G_VENTOY_VERSION; @@ -801,18 +945,29 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) for (i = 0; i < disknum; i ++) { - if (resource_string_value("ventoy", i, "seg", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - g_disk_map_start = strtouq(value, &endpos, 0); - g_disk_map_end = strtouq(endpos + 1, NULL, 0); + G_DEBUG("[map] ventoy segment%d: 0x%llx@0x%llx\n", i, + (long long)g_ventoy_map_data.seglist[i].seg_start_bytes, + (long long)g_ventoy_map_data.seglist[i].seg_end_bytes); + + g_disk_map_start = (off_t)g_ventoy_map_data.seglist[i].seg_start_bytes; + g_disk_map_end = (off_t)g_ventoy_map_data.seglist[i].seg_end_bytes; } else { - printf("Failed to parse ventoy seg %d\n", i); - continue; + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + G_DEBUG("[resource] ventoy segment%d: %s\n", i, value); } - - G_DEBUG("ventoy segment%d: %s\n", i, value); G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); error = g_ventoy_add_disk(sc, pp, i); @@ -828,7 +983,7 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_disk_map_end = 0; } - return (gp); + return (gp); } static void @@ -1066,3 +1221,4 @@ g_ventoy_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, } DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy); +//MODULE_VERSION(geom_ventoy, 0); diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h index e442b246..abe565bd 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h @@ -76,6 +76,33 @@ struct g_ventoy_softc { struct mtx sc_lock; }; #define sc_name sc_geom->name + + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + uint64_t seg_start_bytes; + uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + uint32_t magic1[4]; + uint32_t magic2[4]; + uint64_t segnum; + uint64_t disksize; + uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + uint32_t magic3[4]; +}; +#pragma pack() + +#define VENTOY_MAP_VALID(magic2) \ + (magic2[0] == VENTOY_UNIX_SEG_MAGIC0 && magic2[1] == VENTOY_UNIX_SEG_MAGIC1 && magic2[2] == VENTOY_UNIX_SEG_MAGIC2 && magic2[3] == VENTOY_UNIX_SEG_MAGIC3) + #endif /* _KERNEL */ struct g_ventoy_metadata { diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c index ab507192..9e43f33a 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c @@ -70,8 +70,9 @@ static bool g_ventoy_tasted = false; static off_t g_ventoy_disk_size = 0; static off_t g_disk_map_start = 0; static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; -struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (65536))) = +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = { { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, { 0, 0, 0, 0 }, @@ -200,12 +201,19 @@ g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) g_topology_assert(); gp = pp->geom; - /* On first open, grab an extra "exclusive" bit */ - if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) - de++; - /* ... and let go of it on last close */ - if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) - de--; + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { error = g_access(cp1, dr, dw, de); @@ -687,6 +695,7 @@ g_ventoy_destroy_geom(struct gctl_req *req __unused, static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { int i; + int vlnk = 0; bool ret = true; uint8_t *buf; char uuid[64]; @@ -778,9 +787,12 @@ static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) ret = false; } - if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) { - ret = false; + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } } g_free(buf); @@ -799,8 +811,10 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) int i; int error; int disknum; + int remount = 0; char *endpos; const char *value; + const char *alias = NULL; struct g_geom *gp; struct g_ventoy_metadata md; struct g_ventoy_softc *sc; @@ -824,7 +838,24 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_ventoy_tasted = true; - G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); + + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + + /* hint.ventoy.0.alias=xxx */ + if (resource_string_value("ventoy", 0, "alias", &alias) == 0) + { + G_DEBUG("###### ventoy alias <%s> ######\n", alias); + } + else + { + alias = NULL; + } if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { @@ -895,7 +926,12 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_disk_map_end = 0; } - return (gp); + if (alias) + { + g_geom_add_alias(gp, alias); + } + + return (gp); } static void diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c index 95c2842b..3bb39a19 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c @@ -70,8 +70,9 @@ static bool g_ventoy_tasted = false; static off_t g_ventoy_disk_size = 0; static off_t g_disk_map_start = 0; static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; -struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (65536))) = +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = { { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, { 0, 0, 0, 0 }, @@ -200,17 +201,19 @@ g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) g_topology_assert(); gp = pp->geom; -#if 1 - /* On first open, grab an extra "exclusive" bit */ - if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) - de++; - /* ... and let go of it on last close */ - if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) - de--; -#else - G_DEBUG("g_ventoy_access fake de (%d)-->(0)\n", de); - de = 0; -#endif + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { error = g_access(cp1, dr, dw, de); @@ -726,6 +729,7 @@ g_ventoy_destroy_geom(struct gctl_req *req __unused, static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { int i; + int vlnk = 0; bool ret = true; uint8_t *buf; char uuid[64]; @@ -817,9 +821,12 @@ static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) ret = false; } - if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) { - ret = false; + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } } g_free(buf); @@ -838,6 +845,7 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) int i; int error; int disknum; + int remount = 0; char *endpos; const char *value; const char *alias = NULL; @@ -866,6 +874,13 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + /* hint.ventoy.0.alias=xxx */ if (resource_string_value("ventoy", 0, "alias", &alias) == 0) { diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c index 332ddd2c..a618140e 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c @@ -65,11 +65,22 @@ static g_taste_t g_ventoy_taste; static g_ctl_req_t g_ventoy_config; static g_dumpconf_t g_ventoy_dumpconf; -static const char *g_ventoy_disk_uuid = NULL; +static char g_ventoy_disk_uuid[64]; static bool g_ventoy_tasted = false; static off_t g_ventoy_disk_size = 0; static off_t g_disk_map_start = 0; static off_t g_disk_map_end = 0; +static int g_ventoy_remount = 0; + +struct g_ventoy_map g_ventoy_map_data __attribute__((aligned (4096))) = +{ + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 }, + { 0, 0, 0, 0 }, + 0, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { { 0, 0 } }, + { VENTOY_UNIX_SEG_MAGIC0, VENTOY_UNIX_SEG_MAGIC1, VENTOY_UNIX_SEG_MAGIC2, VENTOY_UNIX_SEG_MAGIC3 } +}; struct g_class g_ventoy_class = { .name = G_VENTOY_CLASS_NAME, @@ -191,12 +202,19 @@ g_ventoy_access(struct g_provider *pp, int dr, int dw, int de) g_topology_assert(); gp = pp->geom; - /* On first open, grab an extra "exclusive" bit */ - if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) - de++; - /* ... and let go of it on last close */ - if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) - de--; + if (g_ventoy_remount) + { + de = 0; + } + else + { + /* On first open, grab an extra "exclusive" bit */ + if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) + de++; + /* ... and let go of it on last close */ + if ((pp->acr + dr) == 0 && (pp->acw + dw) == 0 && (pp->ace + de) == 0) + de--; + } LIST_FOREACH_SAFE(cp1, &gp->consumer, consumer, tmp) { error = g_access(cp1, dr, dw, de); @@ -642,24 +660,52 @@ g_ventoy_destroy_geom(struct gctl_req *req __unused, static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { int i; + int vlnk = 0; + bool ret = true; uint8_t *buf; char uuid[64]; const char *value; struct g_consumer *cp; struct g_geom *gp; + uint8_t mbrdata[] = { + 0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D, + }; if (g_ventoy_disk_size == 0) { - if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - G_DEBUG("ventoy.disksize: %s\n", value); - g_ventoy_disk_size = strtouq(value, NULL, 0); - } + G_DEBUG("ventoy map data is valid. [OK]\n"); - if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0) - { + for (i = 0; i < 16; i++) + { + sprintf(uuid + i * 2, "%02x", g_ventoy_map_data.diskuuid[i]); + } + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", uuid); + g_ventoy_disk_size = g_ventoy_map_data.disksize; + + G_DEBUG("ventoy.disksize: %llu\n", (unsigned long long)g_ventoy_disk_size); G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid); } + else + { + G_DEBUG("ventoy map data is invalid, get from resource\n"); + + if (resource_string_value("ventoy", 0, "disksize", &value) == 0) + { + G_DEBUG("ventoy.disksize: %s\n", value); + g_ventoy_disk_size = strtouq(value, NULL, 0); + } + + if (resource_string_value("ventoy", 0, "diskuuid", &value) == 0) + { + snprintf(g_ventoy_disk_uuid, sizeof(g_ventoy_disk_uuid), "%s", value); + G_DEBUG("ventoy.diskuuid: <%s>\n", value); + } + } } if (g_ventoy_disk_size != pp->mediasize) @@ -700,14 +746,28 @@ static bool g_vtoy_check_disk(struct g_class *mp, struct g_provider *pp) { sprintf(uuid + i * 2, "%02x", buf[0x180 + i]); } - g_free(buf); - - if (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0) + + if (strncmp(g_ventoy_disk_uuid, uuid, 32)) { - return true; + ret = false; } - return false; + if (resource_int_value("ventoy", 0, "vlnk", &vlnk) || (vlnk != 1)) + { + if (memcmp(mbrdata, buf, 0x30) || memcmp(mbrdata + 0x30, buf + 0x190, 16)) + { + ret = false; + } + } + + g_free(buf); + + if (ret) + { + G_DEBUG("ventoy disk check OK\n"); + } + + return ret; } static struct g_geom * @@ -716,8 +776,10 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) int i; int error; int disknum; + int remount = 0; char *endpos; const char *value; + const char *alias = NULL; struct g_geom *gp; struct g_ventoy_metadata md; struct g_ventoy_softc *sc; @@ -741,9 +803,32 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_ventoy_tasted = true; - G_DEBUG("######### ventoy disk <%s> #############\n", pp->name); + G_DEBUG("###### ventoy disk <%s> ######\n", pp->name); - resource_int_value("ventoy", 0, "segnum", &disknum); + /* hint.ventoy.0.remount=1 */ + if (resource_int_value("ventoy", 0, "remount", &remount) == 0 && remount == 1) + { + g_ventoy_remount = 1; + G_DEBUG("###### ventoy remount enabled ######\n"); + } + + /* hint.ventoy.0.alias=xxx */ + if (resource_string_value("ventoy", 0, "alias", &alias) == 0 && alias) + { + G_DEBUG("###### ventoy alias <%s> ######\n", alias); + setenv("kern.devalias.ventoy/IMAGE", alias); + } + + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) + { + disknum = (int)g_ventoy_map_data.segnum; + G_DEBUG("segnum from map data is:<%d>\n", disknum); + } + else + { + resource_int_value("ventoy", 0, "segnum", &disknum); + G_DEBUG("segnum from resource is:<%d>\n", disknum); + } strlcpy(md.md_magic, G_VENTOY_MAGIC, sizeof(md.md_magic)); md.md_version = G_VENTOY_VERSION; @@ -765,18 +850,29 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) for (i = 0; i < disknum; i ++) { - if (resource_string_value("ventoy", i, "seg", &value) == 0) + if (VENTOY_MAP_VALID(g_ventoy_map_data.magic2)) { - g_disk_map_start = strtouq(value, &endpos, 0); - g_disk_map_end = strtouq(endpos + 1, NULL, 0); + G_DEBUG("[map] ventoy segment%d: 0x%llx@0x%llx\n", i, + (long long)g_ventoy_map_data.seglist[i].seg_start_bytes, + (long long)g_ventoy_map_data.seglist[i].seg_end_bytes); + + g_disk_map_start = (off_t)g_ventoy_map_data.seglist[i].seg_start_bytes; + g_disk_map_end = (off_t)g_ventoy_map_data.seglist[i].seg_end_bytes; } else { - printf("Failed to parse ventoy seg %d\n", i); - continue; + if (resource_string_value("ventoy", i, "seg", &value) == 0) + { + g_disk_map_start = strtouq(value, &endpos, 0); + g_disk_map_end = strtouq(endpos + 1, NULL, 0); + } + else + { + printf("Failed to parse ventoy seg %d\n", i); + continue; + } + G_DEBUG("[resource] ventoy segment%d: %s\n", i, value); } - - G_DEBUG("ventoy segment%d: %s\n", i, value); G_VENTOY_DEBUG(1, "Adding disk %s to %s.", pp->name, gp->name); error = g_ventoy_add_disk(sc, pp, i); @@ -792,7 +888,7 @@ g_ventoy_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) g_disk_map_end = 0; } - return (gp); + return (gp); } static void diff --git a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h index e442b246..abe565bd 100644 --- a/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h +++ b/Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h @@ -76,6 +76,33 @@ struct g_ventoy_softc { struct mtx sc_lock; }; #define sc_name sc_geom->name + + +#pragma pack(1) +#define VENTOY_UNIX_SEG_MAGIC0 0x11223344 +#define VENTOY_UNIX_SEG_MAGIC1 0x55667788 +#define VENTOY_UNIX_SEG_MAGIC2 0x99aabbcc +#define VENTOY_UNIX_SEG_MAGIC3 0xddeeff00 +#define VENTOY_UNIX_MAX_SEGNUM 40960 +struct g_ventoy_seg { + uint64_t seg_start_bytes; + uint64_t seg_end_bytes; +}; + +struct g_ventoy_map{ + uint32_t magic1[4]; + uint32_t magic2[4]; + uint64_t segnum; + uint64_t disksize; + uint8_t diskuuid[16]; + struct g_ventoy_seg seglist[VENTOY_UNIX_MAX_SEGNUM]; + uint32_t magic3[4]; +}; +#pragma pack() + +#define VENTOY_MAP_VALID(magic2) \ + (magic2[0] == VENTOY_UNIX_SEG_MAGIC0 && magic2[1] == VENTOY_UNIX_SEG_MAGIC1 && magic2[2] == VENTOY_UNIX_SEG_MAGIC2 && magic2[3] == VENTOY_UNIX_SEG_MAGIC3) + #endif /* _KERNEL */ struct g_ventoy_metadata {