]> glassweightruler.freedombox.rocks Git - Ventoy.git/blobdiff - VtoyTool/vtoydm.c
Fix the boot issue for pfSense 2.7.x (#2775)
[Ventoy.git] / VtoyTool / vtoydm.c
index aa460af0e3d1e0aaae4b26908737a193b6a76c5c..46de17268b83adc94c4e31ad75859821fdbac1b4 100644 (file)
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <linux/fs.h>
+#include <dirent.h>
 #include "biso.h"
 #include "biso_list.h"
 #include "biso_util.h"
 #include "biso_plat.h"
 #include "biso_9660.h"
+#include "vtoytool.h"
 
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
 
 #ifndef USE_DIET_C
+#ifndef __mips__
 typedef unsigned long long uint64_t;
+#endif
 typedef unsigned int    uint32_t;
 #endif
 
@@ -64,6 +68,7 @@ static int verbose = 0;
 #define CMD_DUMP_ISO_INFO     3
 #define CMD_EXTRACT_ISO_FILE  4
 #define CMD_PRINT_EXTRACT_ISO_FILE  5
+#define CMD_PRINT_RAW_TABLE         6
 
 static uint64_t g_iso_file_size;
 static char g_disk_name[128];
@@ -482,12 +487,12 @@ static int vtoydm_print_extract_iso
 
 
 
-static int vtoydm_print_linear_table(const char *img_map_file, const char *diskname)
+static int vtoydm_print_linear_table(const char *img_map_file, const char *diskname, int part, uint64_t offset)
 {
     int i;
     int len;
+    uint32_t disk_sector_num;
     uint32_t sector_start;
-    uint32_t sector_num;
     ventoy_img_chunk *chunk = NULL;
     
     chunk = vtoydm_get_img_map_data(img_map_file, &len);
@@ -499,17 +504,26 @@ static int vtoydm_print_linear_table(const char *img_map_file, const char *diskn
     for (i = 0; i < len / sizeof(ventoy_img_chunk); i++)
     {
         sector_start = chunk[i].img_start_sector;
-        sector_num = chunk[i].img_end_sector - chunk[i].img_start_sector + 1;
+        disk_sector_num = (uint32_t)(chunk[i].disk_end_sector + 1 - chunk[i].disk_start_sector);
 
         /* TBD: to be more flexible */
         #if 0
         printf("%u %u linear %s %llu\n", 
-               (sector_start << 2), (sector_num << 2)
+               (sector_start << 2), disk_sector_num
                diskname, (unsigned long long)chunk[i].disk_start_sector);
         #else
-        printf("%u %u linear %s1 %llu\n", 
-               (sector_start << 2), (sector_num << 2), 
-               diskname, (unsigned long long)chunk[i].disk_start_sector - 2048);
+        if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd"))
+        {
+            printf("%u %u linear %sp%d %llu\n", 
+               (sector_start << 2), disk_sector_num, 
+               diskname, part, (unsigned long long)chunk[i].disk_start_sector - offset);
+        }
+        else
+        {
+            printf("%u %u linear %s%d %llu\n", 
+               (sector_start << 2), disk_sector_num, 
+               diskname, part, (unsigned long long)chunk[i].disk_start_sector - offset);
+        }
         #endif
     }
 
@@ -528,17 +542,162 @@ static int vtoydm_print_help(FILE *fp)
     return 0;        
 }
 
+static uint64_t vtoydm_get_part_start(const char *diskname, int part)
+{
+    int fd;
+    unsigned long long size = 0;
+    char diskpath[256] = {0};
+    char sizebuf[64] = {0};
+
+    if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd"))
+    {
+        snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%sp%d/start", diskname, part);
+    }
+    else
+    {
+        snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%s%d/start", diskname, part);
+    }
+
+    if (access(diskpath, F_OK) >= 0)
+    {
+        debug("get part start from sysfs for %s %d\n", diskname, part);
+        
+        fd = open(diskpath, O_RDONLY | O_BINARY);
+        if (fd >= 0)
+        {
+            read(fd, sizebuf, sizeof(sizebuf));
+            size = strtoull(sizebuf, NULL, 10);
+            close(fd);
+            return size;
+        }
+    }
+    else
+    {
+        debug("%s not exist \n", diskpath);
+    }
+
+    return size;
+}
+
+static uint64_t vtoydm_get_part_secnum(const char *diskname, int part)
+{
+    int fd;
+    unsigned long long size = 0;
+    char diskpath[256] = {0};
+    char sizebuf[64] = {0};
+
+    diskname += 5; /* skip /dev/ */
+
+    if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd"))
+    {
+        snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%sp%d/size", diskname, part);
+    }
+    else
+    {
+        snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%s%d/size", diskname, part);
+    }
+
+    if (access(diskpath, F_OK) >= 0)
+    {
+        debug("get part size from sysfs for %s %d\n", diskname, part);
+        
+        fd = open(diskpath, O_RDONLY | O_BINARY);
+        if (fd >= 0)
+        {
+            read(fd, sizebuf, sizeof(sizebuf));
+            size = strtoull(sizebuf, NULL, 10);
+            close(fd);
+            return size;
+        }
+    }
+    else
+    {
+        debug("%s not exist \n", diskpath);
+    }
+
+    return size;
+}
+
+static int vtoydm_vlnk_convert(char *disk, int len, int *part, uint64_t *offset)
+{
+    int rc = 1;
+    int cnt = 0;
+    int rdlen;
+    FILE *fp = NULL;
+    ventoy_os_param param;
+    char diskname[128] = {0};
+
+    fp = fopen("/ventoy/ventoy_os_param", "rb");
+    if (!fp)
+    {
+        debug("dm vlnk convert not exist %d\n", errno);
+        goto end;
+    }
+
+    memset(&param, 0, sizeof(param));
+    rdlen = (int)fread(&param, 1, sizeof(param), fp);
+    if (rdlen != (int)sizeof(param))
+    {
+        debug("fread failed %d %d\n", rdlen, errno);
+        goto end;
+    }
+
+    debug("dm vlnk convert vtoy_reserved=%d\n", param.vtoy_reserved[6]);
+
+    if (param.vtoy_reserved[6])
+    {
+        cnt = vtoy_find_disk_by_guid(&param, diskname);
+        debug("vtoy_find_disk_by_guid cnt=%d\n", cnt);        
+        if (cnt == 1)
+        {
+            *part = param.vtoy_disk_part_id;
+            *offset = vtoydm_get_part_start(diskname, *part);
+            
+            debug("VLNK <%s> <%s> <P%d> <%llu>\n", disk, diskname, *part, (unsigned long long)(*offset));
+
+            snprintf(disk, len, "/dev/%s", diskname);
+
+            rc = 0;
+        }
+    }
+
+end:
+    if (fp)
+        fclose(fp);
+    return rc;
+}
+
+static int vtoydm_print_raw_linear_table(const char *img_map_file, const char *diskname, int part)
+{
+    uint64_t disk_sector_num;
+
+    disk_sector_num = vtoydm_get_part_secnum(diskname, part);
+
+    if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd"))
+    {
+        printf("0 %lu linear %sp%d 0\n", (unsigned long)disk_sector_num, diskname, part);
+    }
+    else
+    {
+        printf("0 %lu linear %s%d 0\n", (unsigned long)disk_sector_num, diskname, part);
+    }
+    
+    return 0;
+}
+
 int vtoydm_main(int argc, char **argv)
 {
     int ch;
     int cmd = 0;
+    int part = 1;
+    uint64_t offset = 2048;
     unsigned long first_sector = 0;
     unsigned long long file_size = 0;
     char diskname[128] = {0};
     char filepath[300] = {0};
     char outfile[300] = {0};
 
-    while ((ch = getopt(argc, argv, "s:l:o:d:f:v::i::p::c::h::e::E::")) != -1)
+    while ((ch = getopt(argc, argv, "s:l:o:d:f:v::i::p::r::c::h::e::E::")) != -1)
     {
         if (ch == 'd')
         {
@@ -552,6 +711,10 @@ int vtoydm_main(int argc, char **argv)
         {
             cmd = CMD_PRINT_TABLE;
         }
+        else if (ch == 'r')
+        {
+            cmd = CMD_PRINT_RAW_TABLE;
+        }
         else if (ch == 'c')
         {
             cmd = CMD_CREATE_DM;
@@ -604,11 +767,17 @@ int vtoydm_main(int argc, char **argv)
     debug("cmd=%d file=<%s> disk=<%s> first_sector=%lu file_size=%llu\n", 
           cmd, filepath, diskname, first_sector, file_size);
 
+    vtoydm_vlnk_convert(diskname, sizeof(diskname), &part, &offset);
+    
     switch (cmd)
     {
         case CMD_PRINT_TABLE:
         {
-            return vtoydm_print_linear_table(filepath, diskname);
+            return vtoydm_print_linear_table(filepath, diskname, part, offset);
+        }
+        case CMD_PRINT_RAW_TABLE:
+        {
+            return vtoydm_print_raw_linear_table(filepath, diskname, part);
         }
         case CMD_CREATE_DM:
         {