qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/3] Add arg -disk to define new disk with more feat


From: Laurent . Vivier
Subject: [Qemu-devel] [PATCH 2/3] Add arg -disk to define new disk with more features
Date: Sun, 28 Oct 2007 23:43:34 +0100

From: Laurent Vivier <address@hidden(none)>

As for "-cdrom", this patch introduces a new parameter allowing to
define more information for a disk.

The new parameter is "-disk":

    -disk file[,if=type][,bus=n][,unit=m][,cyls=c,heads=h,secs=s[,trans=t]]

where "type" defines the bus type (by default "ide")
      "n" the bus number (by default 0)
      "m" the unit number (by default 0)
      and c,h,s and t define the disk geometry (like -hdachs)
---
 vl.c |  197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 173 insertions(+), 24 deletions(-)

diff --git a/vl.c b/vl.c
index a8c4a81..8408ce4 100644
--- a/vl.c
+++ b/vl.c
@@ -4701,6 +4701,114 @@ void do_info_network(void)
     }
 }
 
+static int disk_init(const char *str, int snapshot)
+{
+    char buf[16];
+    char interface[16];
+    int bus_id, unit_id;
+    int cyls, heads, secs, translation;
+    char *p;
+    char *file;
+
+    file = str;
+    p = str;
+    while (*p != '\0' && *p != ',')
+        p++;
+    if (*p == ',') {
+        *p = '\0';
+        p++;
+    }
+
+    cyls = heads = secs = 0;
+    bus_id = -1;
+    unit_id = -1;
+    translation = BIOS_ATA_TRANSLATION_AUTO;
+    pstrcpy(interface, sizeof(interface), "ide");
+
+    if (get_param_value(buf, sizeof(buf), "bus", p)) {
+        bus_id = strtol(buf, NULL, 0);
+    }
+
+    if (get_param_value(buf, sizeof(buf), "unit", p)) {
+        unit_id = strtol(buf, NULL, 0);
+    }
+
+    if (get_param_value(buf, sizeof(buf), "cyls", p)) {
+        cyls = strtol(buf, NULL, 0);
+    }
+
+    if (get_param_value(buf, sizeof(buf), "heads", p)) {
+        heads = strtol(buf, NULL, 0);
+    }
+
+    if (get_param_value(buf, sizeof(buf), "secs", p)) {
+        secs = strtol(buf, NULL, 0);
+    }
+
+    if (get_param_value(buf, sizeof(buf), "if", p)) {
+        pstrcpy(interface, sizeof(interface), buf);
+    }
+
+    if (get_param_value(buf, sizeof(buf), "trans", p)) {
+        if (!strcmp(buf, "none"))
+            translation = BIOS_ATA_TRANSLATION_NONE;
+        else if (!strcmp(buf, "lba"))
+            translation = BIOS_ATA_TRANSLATION_LBA;
+        else if (!strcmp(buf, "auto"))
+            translation = BIOS_ATA_TRANSLATION_AUTO;
+       else 
+           translation = -1;
+    }
+
+    if ( (cyls || secs || heads) &&
+        ( (cyls < 1 || cyls > 16383) ||
+          (heads < 1 || heads > 16) ||
+          (secs < 1 || secs > 63) ||
+         (translation == -1) ) ) {
+            fprintf(stderr, "qemu: invalid physical CHS format\n");
+           return -1;
+    }
+
+    if (strcmp(interface, "ide") == 0) {
+        static int disk_index = -1;
+       
+       disk_index++;
+
+       if (bus_id == -1) {
+           bus_id = disk_index / 2;
+           if (unit_id == -1)
+               unit_id = disk_index % 2;
+       } else if (unit_id == -1)
+           unit_id = 0;
+
+       disk_index = bus_id * 2 + unit_id;
+
+        snprintf(buf, sizeof(buf), "hd%c", disk_index + 'a');
+
+        bs_table[disk_index] = bdrv_new(buf);
+
+        if (bdrv_open(bs_table[disk_index], file,
+                      snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
+            fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
+                    file);
+                  return -1;
+        }
+ 
+        if (cyls != 0) {
+            bdrv_set_geometry_hint(bs_table[disk_index],
+                                  cyls, heads, secs);
+            bdrv_set_translation_hint(bs_table[disk_index], translation);
+        }
+        return 0;
+    } else if (strcmp(interface, "scsi") == 0) {
+        /* TODO */
+    }
+
+    fprintf(stderr, "unsupported bus type '%s' for cdrom '%s'\n",
+            interface, file);
+    return -1;
+}
+
 #define MAX_CDROMS             4
 #ifdef TARGET_PPC
 #define DEFAULT_CDROM_BUS      0
@@ -7063,6 +7171,8 @@ static void help(int exitcode)
            "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
            "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
            "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
+          "-disk 
file[,if=type][,bus=n][,unit=m][,cyls=c,heads=h,secs=s[,trans=t]]\n"
+          "                use 'file' as a disk image\n"
            "-cdrom file[,if=type][,bus=n][,unit=m]\n"
           "                use 'file' as cdrom image\n"
           "                (by default cdrom is ide1 master 
(if=ide,bus=1,unit=0))\n"
@@ -7214,6 +7324,7 @@ enum {
     QEMU_OPTION_hdb,
     QEMU_OPTION_hdc,
     QEMU_OPTION_hdd,
+    QEMU_OPTION_disk,
     QEMU_OPTION_cdrom,
     QEMU_OPTION_mtdblock,
     QEMU_OPTION_sd,
@@ -7302,6 +7413,7 @@ const QEMUOption qemu_options[] = {
     { "hdb", HAS_ARG, QEMU_OPTION_hdb },
     { "hdc", HAS_ARG, QEMU_OPTION_hdc },
     { "hdd", HAS_ARG, QEMU_OPTION_hdd },
+    { "disk", HAS_ARG, QEMU_OPTION_disk },
     { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
     { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
     { "sd", HAS_ARG, QEMU_OPTION_sd },
@@ -7629,7 +7741,7 @@ int main(int argc, char **argv)
     int i, pflash_index;
     int snapshot, linux_boot;
     const char *initrd_filename;
-    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
+    const char *fd_filename[MAX_FD];
     const char *pflash_filename[MAX_PFLASH];
     const char *sd_filename;
     const char *mtd_filename;
@@ -7637,9 +7749,12 @@ int main(int argc, char **argv)
     DisplayState *ds = &display_state;
     int cyls, heads, secs, translation;
     char net_clients[MAX_NET_CLIENTS][256];
+    char disks[MAX_DISKS][256];
     char cdroms[MAX_CDROMS][256];
     int nb_net_clients;
+    int nb_disks;
     int nb_cdroms;
+    int hda_index = -1;
     int optind;
     const char *r, *optarg;
     CharDriverState *monitor_hd;
@@ -7694,8 +7809,6 @@ int main(int argc, char **argv)
     initrd_filename = NULL;
     for(i = 0; i < MAX_FD; i++)
         fd_filename[i] = NULL;
-    for(i = 0; i < MAX_DISKS; i++)
-        hd_filename[i] = NULL;
     for(i = 0; i < MAX_PFLASH; i++)
         pflash_filename[i] = NULL;
     pflash_index = 0;
@@ -7728,6 +7841,7 @@ int main(int argc, char **argv)
     usb_devices_index = 0;
 
     nb_net_clients = 0;
+    nb_disks = 0;
     nb_cdroms = 0;
 
     nb_nics = 0;
@@ -7739,7 +7853,10 @@ int main(int argc, char **argv)
             break;
         r = argv[optind];
         if (r[0] != '-') {
-            hd_filename[0] = argv[optind++];
+           hda_index = nb_disks;
+            snprintf(disks[nb_disks], sizeof(disks[0]),
+                     "%s,bus=0,unit=0", argv[optind++]);
+            nb_disks++;
         } else {
             const QEMUOption *popt;
 
@@ -7799,15 +7916,51 @@ int main(int argc, char **argv)
                 initrd_filename = optarg;
                 break;
             case QEMU_OPTION_hda:
+                if (nb_disks >= MAX_DISKS) {
+                    fprintf(stderr, "qemu: too many disks\n");
+                    exit(1);
+               }
+               hda_index = nb_disks;
+               if (cyls == 0)
+                   snprintf(disks[nb_disks], sizeof(disks[0]),
+                            "%s,bus=0,unit=0", optarg);
+               else {
+                   snprintf(disks[nb_disks], sizeof(disks[0]),
+                            "%s,bus=0,unit=0,cyls=%d,heads=%d,secs=%d%s",
+                            optarg, cyls, heads, secs,
+                            translation == BIOS_ATA_TRANSLATION_LBA ?
+                               ",trans=lba" :
+                            translation == BIOS_ATA_TRANSLATION_NONE ?
+                                ",trans=none" : "");
+               }
+                nb_disks++;
+               break;
             case QEMU_OPTION_hdb:
             case QEMU_OPTION_hdc:
             case QEMU_OPTION_hdd:
                 {
                     int hd_index;
+                    if (nb_disks >= MAX_DISKS) {
+                        fprintf(stderr, "qemu: too many disks\n");
+                        exit(1);
+                   }
                     hd_index = popt->index - QEMU_OPTION_hda;
-                    hd_filename[hd_index] = optarg;
+                   snprintf(disks[nb_disks], sizeof(disks[0]),
+                            "%s,bus=%d,unit=%d", optarg,
+                            hd_index / 2, hd_index % 2);
+                    nb_disks++;
                 }
                 break;
+           case QEMU_OPTION_disk:
+                if (nb_disks >= MAX_DISKS) {
+                    fprintf(stderr, "qemu: too many disks\n");
+                    exit(1);
+                }
+                pstrcpy(disks[nb_disks],
+                        sizeof(disks[0]),
+                        optarg);
+                nb_disks++;
+                break;
             case QEMU_OPTION_mtdblock:
                 mtd_filename = optarg;
                 break;
@@ -7858,6 +8011,15 @@ int main(int argc, char **argv)
                         fprintf(stderr, "qemu: invalid physical CHS format\n");
                         exit(1);
                     }
+                   if (hda_index != -1)
+                       snprintf(disks[hda_index] + strlen(disks[hda_index]),
+                                sizeof(disks[0]) - strlen(disks[hda_index]),
+                                ",cyls=%d,heads=%d,secs=%d%s",
+                                cyls, heads, secs,
+                                translation == BIOS_ATA_TRANSLATION_LBA ?
+                                   ",trans=lba" :
+                                translation == BIOS_ATA_TRANSLATION_NONE ?
+                                    ",trans=none" : "");
                 }
                 break;
             case QEMU_OPTION_nographic:
@@ -8245,13 +8407,13 @@ int main(int argc, char **argv)
 
     if (!linux_boot &&
         boot_device != 'n' &&
-        hd_filename[0] == '\0' &&
+        nb_disks == 0 &&
         (nb_cdroms >= 0 && cdroms[0] == '\0') &&
         fd_filename[0] == '\0')
         help(1);
 
     /* boot to floppy or the default cd if no hard disk defined yet */
-    if (hd_filename[0] == '\0' && boot_device == 'c') {
+    if (nb_disks == 0 && boot_device == 'c') {
         if (fd_filename[0] != '\0')
             boot_device = 'a';
         else
@@ -8337,23 +8499,10 @@ int main(int argc, char **argv)
                exit(1);
 
     /* open the virtual block devices */
-    for(i = 0; i < MAX_DISKS; i++) {
-        if (hd_filename[i]) {
-            char buf[64];
-            snprintf(buf, sizeof(buf), "hd%c", i + 'a');
-            bs_table[i] = bdrv_new(buf);
-
-            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? 
BDRV_O_SNAPSHOT : 0) < 0) {
-                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
-                        hd_filename[i]);
-                exit(1);
-            }
-            if (i == 0 && cyls != 0) {
-                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
-                bdrv_set_translation_hint(bs_table[i], translation);
-            }
-        }
-    }
+
+    for(i = 0; i < nb_disks; i++)
+        if (disk_init(disks[i], snapshot) == -1)
+            exit(1);
 
     /* we always create at least one floppy disk */
     fd_table[0] = bdrv_new("fda");
-- 
1.4.4.4





reply via email to

[Prev in Thread] Current Thread [Next in Thread]