add "serial" parameter to -drive flag
PATCH v2 1/1 add "serial" parameter to -drive flag
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 <[email protected]>
hw/ide.c +9 -9
@@ -386,6 +386,7 @@ typedef struct IDEState {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 @@ static void ide_identify(IDEState *s) {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 @@ static void ide_identify(IDEState *s)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_identify(IDEState *s)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 @@ static void ide_atapi_identify(IDEState *s) 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 @@ static void ide_cfata_identify(IDEState *s) {uint16_t *p;uint32_t cur_sec; -char buf[20 ]; p = (uint16_t *) s->identify_data;if (s->identify_set)
@@ -668,8 +664,7 @@ static void ide_cfata_identify(IDEState *s)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 @@ static void ide_init2(IDEState *ide_state, } } 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);
hw/scsi-disk.c +13 -4
@@ -13,6 +13,8 @@* the host adapter emulator. */ +#include <qemu-common.h> +#include <sysemu.h> //#define DEBUG_SCSI #ifdef DEBUG_SCSI
@@ -68,6 +70,7 @@ struct SCSIDeviceStateor from the AIO completion routines. */ scsi_completionfn completion;void *opaque; +char drive_serial_str[21 ]; };/* Global pool of SCSIRequest structures. */
@@ -408,6 +411,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,break ;case 0x80 : { +int l; +/* Device serial number, optional */ if (len <4 ) { BADF("Error: EVPD[Serial number] Inquiry buffer "
@@ -416,6 +421,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, }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 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, 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 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq, }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;
qemu-doc.texi +2 -0
@@ -274,6 +274,8 @@ These options have the same definition as they have in @option{-hdachs}. 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
sysemu.h +2 -0
@@ -131,6 +131,7 @@ typedef struct DriveInfo {BlockInterfaceType type;int bus;int unit; +char serial[21 ]; } DriveInfo;#define MAX_IDE_DEVS 2
@@ -142,6 +143,7 @@ extern DriveInfo drives_table[MAX_DRIVES+1];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 */
vl.c +18 -2
@@ -2196,6 +2196,17 @@ int drive_get_max_bus(BlockInterfaceType type)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 @@ static int drive_init(struct drive_opt *arg, int snapshot,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 int drive_init(struct drive_opt *arg, int snapshot,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 @@ static int drive_init(struct drive_opt *arg, int snapshot,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 @@ static int drive_init(struct drive_opt *arg, int snapshot, 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 @@ static void help(int exitcode)"-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"
--
Gleb.
Anthony Liguori
AppliedQuoted 5 lines · 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.
Applied. Thanks.
Regards,
Anthony Liguori