]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1. Fix the bug when booing Easy Recovery Essentional for Windows10.
authorlongpanda <admin@ventoy.net>
Tue, 8 Mar 2022 10:27:07 +0000 (18:27 +0800)
committerlongpanda <admin@ventoy.net>
Tue, 8 Mar 2022 10:27:07 +0000 (18:27 +0800)
2. Fix the bug when booting FreeBSD 13.0 by F2 browser mode.

23 files changed:
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c
INSTALL/grub/grub.cfg
INSTALL/ventoy/ventoy_unix.cpio
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/32/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/10.x/64/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/32/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/11.x/64/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/32/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/12.x/64/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/32/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/13.x/64/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/32/geom_ventoy.ko.xz
Unix/ventoy_unix/FreeBSD/geom_ventoy_ko/9.x/64/geom_ventoy.ko.xz
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.c
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/10.x/sys/geom/ventoy/g_ventoy.h
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.c
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/11.x/sys/geom/ventoy/g_ventoy.h
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/12.x/sys/geom/ventoy/g_ventoy.c
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/13.x/sys/geom/ventoy/g_ventoy.c
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.c
Unix/ventoy_unix_src/FreeBSD/geom_ventoy_src/9.x/sys/geom/ventoy/g_ventoy.h

index 6e40f426281e02084afab66e935298b1ddd954f3..93ad678e3f5e5047be2424fd4fe08c68c7ac9ce1 100644 (file)
@@ -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 },
index 763ed1790fc04c23ba2d78b1022f216126a41b9f..dfffbe856becee7c32ed55f11793dfec95be90fc 100644 (file)
@@ -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);
index dbb30e17ea2a2e076574f6bd86e892360a6a090f..8ff212488fb68b1799d78db78edf98d7fae65f03 100644 (file)
@@ -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;
         }
index e2998ceba9480180e7654117625e156d585689b0..d0e27f53f07abc6e42b2efd276f2041d9e8a839d 100644 (file)
@@ -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
         
index 22d6af4d73e336b00ccbc83a87de2ea0b0d3d168..b613602706c2d286dcf777829a2400e7adad3069 100644 (file)
Binary files a/INSTALL/ventoy/ventoy_unix.cpio and b/INSTALL/ventoy/ventoy_unix.cpio differ
index e1b5d090df1578fc42cb0f74bcfd2ece994753ef..36db91407e39efcea0d1a392c2149cb27037c41e 100644 (file)
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
index 7bfa9793baadb5ec2034390de72d3f2b7ea728b5..e044f3cc0a51e9a0855b48dd19f0db25b8e50443 100644 (file)
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
index 701274e9b1c4ae69dc4f392ab0329f9d7eede4bf..ae1ad2b79a7061b26911b129afe1e528ec9aaf2e 100644 (file)
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
index 2fce19c35d4e14c01a2354d6cf2aec8818a5a1cb..571bcfcb48b54810399e94ac5b93b7625eae1c2b 100644 (file)
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
index 710122b44331e6a13b99db67bb9d2425859b98e1..1381aac0b263d1df2d59e07fa87262f2ed5d10ec 100644 (file)
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
index ed11c653001bfa3690d2a427234654bedebbf427..647cde82d3b76c80c4d12c4bb2c29fe333be4aa8 100644 (file)
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
index 27666a9c2033046d58d5d087df62cad6ff863d70..412e31c2de25933e08bc56c4d141e6a29080d8db 100644 (file)
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
index 7bbca670265d1b60e4dd58c08a9e66ce55217816..f5d92658d8594f0ea30f07467ea675a5c2ad07b3 100644 (file)
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
index 8963f9ecf576d769dfcb45720a6d5365bdc3edfc..ab64fe9b9a5c2eb75f4cde09704111e69f242dad 100644 (file)
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
index 49385f600e21edfbcec28132db843fedd79ac84e..b8caeafa1cde1c3b92842587b860154fe3abe745 100644 (file)
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
index 332ddd2ca0a799b86aa79c6f83cca2fa47ce65d6..a618140ef17de229ed796d5026b73f407dff5251 100644 (file)
@@ -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,23 +660,51 @@ 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");
+
+            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);
         }
-
-        if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0)
+        else
         {
-            G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid);
+            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);
+            }
         }
     }
 
@@ -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]);
     }
+
+    if (strncmp(g_ventoy_disk_uuid, uuid, 32))
+    {
+        ret = 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 (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0)
+
+    if (ret)
     {
-        return true;
+        G_DEBUG("ventoy disk check OK\n");
     }
 
-    return false;
+    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
index e442b246efccfaeb10366a31c71fcb8f70e2735a..abe565bdb9fb7b75cd556453be1d5aa8a83718ab 100644 (file)
@@ -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 {
index 5e8642f7bab109a4f1136f18618c3e5f00dc3181..be9780ee9a5ac89127fe2f646368d526ca832335 100644 (file)
@@ -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,23 +696,51 @@ 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");
+
+            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);
         }
-
-        if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0)
+        else
         {
-            G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid);
+            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);
+            }
         }
     }
 
@@ -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]);
     }
+
+    if (strncmp(g_ventoy_disk_uuid, uuid, 32))
+    {
+        ret = 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 (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0)
+    if (firstflag == 0)
     {
-        return true;
+        /* 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;
     }
 
-    return false;
+    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);
index e442b246efccfaeb10366a31c71fcb8f70e2735a..abe565bdb9fb7b75cd556453be1d5aa8a83718ab 100644 (file)
@@ -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 {
index ab5071921d04bc91e410ef4357eb2fcda52d6836..9e43f33aa7f4374b80078825bacae92e3dbf14ed 100644 (file)
@@ -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
index 95c2842b6cef0a5369cc1a7d864fc4350adebc95..3bb39a190a5ed55bde654c267e543acf72be5f46 100644 (file)
@@ -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)
     {
index 332ddd2ca0a799b86aa79c6f83cca2fa47ce65d6..a618140ef17de229ed796d5026b73f407dff5251 100644 (file)
@@ -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,23 +660,51 @@ 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");
+
+            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);
         }
-
-        if (resource_string_value("ventoy", 0, "diskuuid", &g_ventoy_disk_uuid) == 0)
+        else
         {
-            G_DEBUG("ventoy.diskuuid: <%s>\n", g_ventoy_disk_uuid);
+            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);
+            }
         }
     }
 
@@ -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]);
     }
+
+    if (strncmp(g_ventoy_disk_uuid, uuid, 32))
+    {
+        ret = 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 (strncmp(g_ventoy_disk_uuid, uuid, 32) == 0)
+
+    if (ret)
     {
-        return true;
+        G_DEBUG("ventoy disk check OK\n");
     }
 
-    return false;
+    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
index e442b246efccfaeb10366a31c71fcb8f70e2735a..abe565bdb9fb7b75cd556453be1d5aa8a83718ab 100644 (file)
@@ -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 {