2. Fix the bug when booting FreeBSD 13.0 by F2 browser mode.
{ "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 },
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);
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;
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];
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);
(void)argc;
(void)args;
+ g_unix_vlnk_boot = 0;
g_mod_search_magic = 0;
g_conf_new_len = 0;
g_mod_new_len = 0;
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;
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[] =
{
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;
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)
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;
}
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
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
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,
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);
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);
+ }
}
}
{
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 *
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;
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;
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);
g_disk_map_end = 0;
}
- return (gp);
+ return (gp);
}
static void
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 {
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,
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);
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);
+ }
}
}
{
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 *
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;
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;
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);
g_disk_map_end = 0;
}
- return (gp);
+ return (gp);
}
static void
}
DECLARE_GEOM_CLASS(g_ventoy_class, g_ventoy);
+//MODULE_VERSION(geom_ventoy, 0);
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 {
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 },
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);
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];
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);
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;
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))
{
g_disk_map_end = 0;
}
- return (gp);
+ if (alias)
+ {
+ g_geom_add_alias(gp, alias);
+ }
+
+ return (gp);
}
static void
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 },
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);
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];
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);
int i;
int error;
int disknum;
+ int remount = 0;
char *endpos;
const char *value;
const char *alias = NULL;
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)
{
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,
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);
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);
+ }
}
}
{
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 *
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;
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;
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);
g_disk_map_end = 0;
}
- return (gp);
+ return (gp);
}
static void
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 {