[Qemu-devel] qemu -boot d -cdrom /dev/cd0 on FreeBSD is not good
Juergen Lock
qemu-l at jelal.kn-bremen.de
Tue Nov 16 10:22:19 PST 2004
On Tue, Nov 16, 2004 at 02:48:34AM +0900, Norikatsu Shigemura wrote:
> I tried to install Windows XP SP2 on qemu over FreeBSD 6-current
> like following command, but failed.
>
> # qemu -boot d -cdrom /dev/cd0 windows.img
>
Yeah physical cdroms don't work currently as mentioned in the pkg-message...
> Because find_image_format on qemu/block.c is failed. This
> problem can be confirmed like following program.
> - - - - - - - - - - - - - - - - - - - - - - - -
> #include <fcntl.h>
> #include <unistd.h>
> #include <stdio.h>
> int main(void)
> {
> char buf[2048];
> int fd = open("/dev/cd0", O_RDONLY);
> if( read(fd, buf, sizeof(buf)) < 0 ) { /* no problem */
> perror("[1] read error.");
> }
> if( read(fd, buf, sizeof(buf) / 2) < 0 ) { /* problem */
> perror("[2] read error.");
> }
> }
> - - - - - - - - - - - - - - - - - - - - - - - -
>
> Adhoc-ly, I changed "buf" size to 2048. and confirmed this
> problem was fixed.
> - - - - - - - - - - - - - - - - - - - - - - - -
> static BlockDriver *find_image_format(const char *filename)
> {
> int fd, ret, score, score_max;
> BlockDriver *drv1, *drv;
> uint8_t buf[1024]; => buf[2048]
> (snip)
> ret = read(fd, buf, sizeof(buf));
> if (ret < 0) {
> close(fd);
> return NULL;
> }
> (snip)
> - - - - - - - - - - - - - - - - - - - - - - - -
> Obtained from: qemu-0.6.1
>
That's all there is to it? Heh. Antony made it sound like it needs
much more! :)
> I think magic number 2048 is sector size, but I don't know
> how to get valid read size. Anyone, do you have any idea?
>
On 5.x and later you can use the DIOCGSECTORSIZE ioctl. Here's
the relevant part of the patch I'll use in the next port update:
Index: qemu/block.c
@@ -103,14 +103,25 @@
{
int fd, ret, score, score_max;
BlockDriver *drv1, *drv;
- uint8_t buf[1024];
+ uint8_t *buf;
+ size_t bufsize = 1024;
+ u_int sectorsize = 512;
fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
if (fd < 0)
return NULL;
- ret = read(fd, buf, sizeof(buf));
+#ifdef DIOCGSECTORSIZE
+ if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) &&
+ sectorsize > bufsize)
+ bufsize = sectorsize;
+#endif
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
+ ret = read(fd, buf, bufsize);
if (ret < 0) {
close(fd);
+ free(buf);
return NULL;
}
close(fd);
@@ -124,6 +135,7 @@
drv = drv1;
}
}
+ free(buf);
return drv;
}
Cheers,
Juergen
More information about the freebsd-hackers
mailing list