mirror of https://github.com/ventoy/Ventoy.git
1. Fix the bug when booing Easy Recovery Essentional for Windows10.
2. Fix the bug when booting FreeBSD 13.0 by F2 browser mode.
This commit is contained in:
parent
6d4f5ff00b
commit
ce862da402
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue