From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LKcGk-0005Fn-2q for qemu-devel@nongnu.org; Wed, 07 Jan 2009 12:32:38 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LKcGi-0005EP-EF for qemu-devel@nongnu.org; Wed, 07 Jan 2009 12:32:37 -0500 Received: from [199.232.76.173] (port=39767 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LKcGi-0005EF-3g for qemu-devel@nongnu.org; Wed, 07 Jan 2009 12:32:36 -0500 Received: from savannah.gnu.org ([199.232.41.3]:42171 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LKcGh-0003tL-Av for qemu-devel@nongnu.org; Wed, 07 Jan 2009 12:32:35 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1LKcGg-0002Q7-Da for qemu-devel@nongnu.org; Wed, 07 Jan 2009 17:32:34 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1LKcGf-0002Pr-QZ for qemu-devel@nongnu.org; Wed, 07 Jan 2009 17:32:34 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Wed, 07 Jan 2009 17:32:33 +0000 Subject: [Qemu-devel] [6214] add "serial" parameter to -drive flag (Gleb Natapov) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 6214 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6214 Author: aliguori Date: 2009-01-07 17:32:33 +0000 (Wed, 07 Jan 2009) Log Message: ----------- add "serial" parameter to -drive flag (Gleb Natapov) Windows calculates HW "uniqueness" based on a hard drive serial number among other things. The patch allows to specify drive serial number from a command line. Signed-off-by: Gleb Natapov Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/hw/ide.c trunk/hw/scsi-disk.c trunk/qemu-doc.texi trunk/sysemu.h trunk/vl.c Modified: trunk/hw/ide.c =================================================================== --- trunk/hw/ide.c 2009-01-07 17:22:19 UTC (rev 6213) +++ trunk/hw/ide.c 2009-01-07 17:32:33 UTC (rev 6214) @@ -386,6 +386,7 @@ PCIDevice *pci_dev; struct BMDMAState *bmdma; int drive_serial; + char drive_serial_str[21]; /* ide regs */ uint8_t feature; uint8_t error; @@ -531,7 +532,6 @@ { uint16_t *p; unsigned int oldsize; - char buf[20]; if (s->identify_set) { memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); @@ -546,8 +546,7 @@ put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */ put_le16(p + 5, 512); /* XXX: retired, remove ? */ put_le16(p + 6, s->sectors); - snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial); - padstr((char *)(p + 10), buf, 20); /* serial number */ + padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */ put_le16(p + 20, 3); /* XXX: retired, remove ? */ put_le16(p + 21, 512); /* cache size in sectors */ put_le16(p + 22, 4); /* ecc bytes */ @@ -601,7 +600,6 @@ static void ide_atapi_identify(IDEState *s) { uint16_t *p; - char buf[20]; if (s->identify_set) { memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); @@ -612,8 +610,7 @@ p = (uint16_t *)s->io_buffer; /* Removable CDROM, 50us response, 12 byte packets */ put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0)); - snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial); - padstr((char *)(p + 10), buf, 20); /* serial number */ + padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */ put_le16(p + 20, 3); /* buffer type */ put_le16(p + 21, 512); /* cache size in sectors */ put_le16(p + 22, 4); /* ecc bytes */ @@ -652,7 +649,6 @@ { uint16_t *p; uint32_t cur_sec; - char buf[20]; p = (uint16_t *) s->identify_data; if (s->identify_set) @@ -668,8 +664,7 @@ put_le16(p + 6, s->sectors); /* Default sectors per track */ put_le16(p + 7, s->nb_sectors >> 16); /* Sectors per card */ put_le16(p + 8, s->nb_sectors); /* Sectors per card */ - snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial); - padstr((char *)(p + 10), buf, 20); /* Serial number in ASCII */ + padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */ put_le16(p + 22, 0x0004); /* ECC bytes */ padstr((char *) (p + 23), QEMU_VERSION, 8); /* Firmware Revision */ padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */ @@ -2714,6 +2709,11 @@ } } s->drive_serial = drive_serial++; + strncpy(s->drive_serial_str, drive_get_serial(s->bs), + sizeof(s->drive_serial_str)); + if (strlen(s->drive_serial_str) == 0) + snprintf(s->drive_serial_str, sizeof(s->drive_serial_str), + "QM%05d", s->drive_serial); s->irq = irq; s->sector_write_timer = qemu_new_timer(vm_clock, ide_sector_write_timer_cb, s); Modified: trunk/hw/scsi-disk.c =================================================================== --- trunk/hw/scsi-disk.c 2009-01-07 17:22:19 UTC (rev 6213) +++ trunk/hw/scsi-disk.c 2009-01-07 17:32:33 UTC (rev 6214) @@ -13,6 +13,8 @@ * the host adapter emulator. */ +#include +#include //#define DEBUG_SCSI #ifdef DEBUG_SCSI @@ -68,6 +70,7 @@ or from the AIO completion routines. */ scsi_completionfn completion; void *opaque; + char drive_serial_str[21]; }; /* Global pool of SCSIRequest structures. */ @@ -408,6 +411,8 @@ break; case 0x80: { + int l; + /* Device serial number, optional */ if (len < 4) { BADF("Error: EVPD[Serial number] Inquiry buffer " @@ -416,6 +421,7 @@ } DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len); + l = MIN(len, strlen(s->drive_serial_str)); r->buf_len = 0; @@ -428,9 +434,9 @@ outbuf[r->buf_len++] = 0x80; // this page outbuf[r->buf_len++] = 0x00; - outbuf[r->buf_len++] = 0x01; // 1 byte data follow - - outbuf[r->buf_len++] = '0'; // 1 byte data follow + outbuf[r->buf_len++] = l; + memcpy(&outbuf[r->buf_len], s->drive_serial_str, l); + r->buf_len += l; } break; @@ -812,7 +818,10 @@ } else { s->cluster_size = 1; } - + strncpy(s->drive_serial_str, drive_get_serial(s->bdrv), + sizeof(s->drive_serial_str)); + if (strlen(s->drive_serial_str) == 0) + strcpy(s->drive_serial_str, "0"); d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice)); d->state = s; d->destroy = scsi_destroy; Modified: trunk/qemu-doc.texi =================================================================== --- trunk/qemu-doc.texi 2009-01-07 17:22:19 UTC (rev 6213) +++ trunk/qemu-doc.texi 2009-01-07 17:32:33 UTC (rev 6214) @@ -274,6 +274,8 @@ Specify which disk @var{format} will be used rather than detecting the format. Can be used to specifiy format=raw to avoid interpreting an untrusted format header. +@item serial=@var{serial} +This option specifies the serial number to assign to the device. @end table By default, writethrough caching is used for all block device. This means that Modified: trunk/sysemu.h =================================================================== --- trunk/sysemu.h 2009-01-07 17:22:19 UTC (rev 6213) +++ trunk/sysemu.h 2009-01-07 17:32:33 UTC (rev 6214) @@ -131,6 +131,7 @@ BlockInterfaceType type; int bus; int unit; + char serial[21]; } DriveInfo; #define MAX_IDE_DEVS 2 @@ -142,6 +143,7 @@ extern int drive_get_index(BlockInterfaceType type, int bus, int unit); extern int drive_get_max_bus(BlockInterfaceType type); +extern const char *drive_get_serial(BlockDriverState *bdrv); /* serial ports */ Modified: trunk/vl.c =================================================================== --- trunk/vl.c 2009-01-07 17:22:19 UTC (rev 6213) +++ trunk/vl.c 2009-01-07 17:32:33 UTC (rev 6214) @@ -2196,6 +2196,17 @@ return max_bus; } +const char *drive_get_serial(BlockDriverState *bdrv) +{ + int index; + + for (index = 0; index < nb_drives; index++) + if (drives_table[index].bdrv == bdrv) + return drives_table[index].serial; + + return "\0"; +} + static void bdrv_format_print(void *opaque, const char *name) { fprintf(stderr, " %s", name); @@ -2207,6 +2218,7 @@ char buf[128]; char file[1024]; char devname[128]; + char serial[21]; const char *mediastr = ""; BlockInterfaceType type; enum { MEDIA_DISK, MEDIA_CDROM } media; @@ -2222,7 +2234,7 @@ static const char * const params[] = { "bus", "unit", "if", "index", "cyls", "heads", "secs", "trans", "media", "snapshot", "file", - "cache", "format", NULL }; + "cache", "format", "serial", NULL }; if (check_params(buf, sizeof(buf), params, str) < 0) { fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n", @@ -2409,6 +2421,9 @@ else pstrcpy(file, sizeof(file), arg->file); + if (!get_param_value(serial, sizeof(serial), "serial", str)) + memset(serial, 0, sizeof(serial)); + /* compute bus and unit according index */ if (index != -1) { @@ -2472,6 +2487,7 @@ drives_table[nb_drives].type = type; drives_table[nb_drives].bus = bus_id; drives_table[nb_drives].unit = unit_id; + strncpy(drives_table[nb_drives].serial, serial, sizeof(serial)); nb_drives++; switch(type) { @@ -3826,7 +3842,7 @@ "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n" " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n" - " [,cache=writethrough|writeback|none][,format=f]\n" + " [,cache=writethrough|writeback|none][,format=f][,serial=s]\n" " use 'file' as a drive image\n" "-mtdblock file use 'file' as on-board Flash memory image\n" "-sd file use 'file' as SecureDigital card image\n"