mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-05-14 23:24:43 -04:00
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
23 changed files with 658 additions and 120 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue