Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xing Lin
qemu
Commits
faea38e7
Commit
faea38e7
authored
Aug 05, 2006
by
bellard
Browse files
multiple snapshot support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@2086
c046a42c-6fe2-441c-8c8c-71466251a162
parent
42ca6388
Changes
6
Hide whitespace changes
Inline
Side-by-side
block.c
View file @
faea38e7
...
...
@@ -494,12 +494,10 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
}
}
#if 0
/* not necessary now */
static
int
bdrv_pread_em
(
BlockDriverState
*
bs
,
int64_t
offset
,
void
*buf
1
, int count1)
uint8_t
*
buf
,
int
count1
)
{
uint8_t *buf = buf1;
uint8_t
tmp_buf
[
SECTOR_SIZE
];
int
len
,
nb_sectors
,
count
;
int64_t
sector_num
;
...
...
@@ -542,9 +540,8 @@ static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
}
static
int
bdrv_pwrite_em
(
BlockDriverState
*
bs
,
int64_t
offset
,
const
void
*buf
1
, int count1)
const
uint8_t
*
buf
,
int
count1
)
{
const uint8_t *buf = buf1;
uint8_t
tmp_buf
[
SECTOR_SIZE
];
int
len
,
nb_sectors
,
count
;
int64_t
sector_num
;
...
...
@@ -589,7 +586,6 @@ static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
}
return
count1
;
}
#endif
/**
* Read with byte offsets (needed only for file protocols)
...
...
@@ -602,7 +598,7 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_pread
)
return
-
ENOTSUP
;
return
bdrv_pread_em
(
bs
,
offset
,
buf1
,
count1
)
;
return
drv
->
bdrv_pread
(
bs
,
offset
,
buf1
,
count1
);
}
...
...
@@ -617,7 +613,7 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_pwrite
)
return
-
ENOTSUP
;
return
bdrv_pwrite_em
(
bs
,
offset
,
buf1
,
count1
)
;
return
drv
->
bdrv_pwrite
(
bs
,
offset
,
buf1
,
count1
);
}
...
...
@@ -859,6 +855,137 @@ void bdrv_get_backing_filename(BlockDriverState *bs,
}
}
int
bdrv_write_compressed
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
const
uint8_t
*
buf
,
int
nb_sectors
)
{
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_write_compressed
)
return
-
ENOTSUP
;
return
drv
->
bdrv_write_compressed
(
bs
,
sector_num
,
buf
,
nb_sectors
);
}
int
bdrv_get_info
(
BlockDriverState
*
bs
,
BlockDriverInfo
*
bdi
)
{
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_get_info
)
return
-
ENOTSUP
;
memset
(
bdi
,
0
,
sizeof
(
*
bdi
));
return
drv
->
bdrv_get_info
(
bs
,
bdi
);
}
/**************************************************************/
/* handling of snapshots */
int
bdrv_snapshot_create
(
BlockDriverState
*
bs
,
QEMUSnapshotInfo
*
sn_info
)
{
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_snapshot_create
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_create
(
bs
,
sn_info
);
}
int
bdrv_snapshot_goto
(
BlockDriverState
*
bs
,
const
char
*
snapshot_id
)
{
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_snapshot_goto
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_goto
(
bs
,
snapshot_id
);
}
int
bdrv_snapshot_delete
(
BlockDriverState
*
bs
,
const
char
*
snapshot_id
)
{
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_snapshot_delete
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_delete
(
bs
,
snapshot_id
);
}
int
bdrv_snapshot_list
(
BlockDriverState
*
bs
,
QEMUSnapshotInfo
**
psn_info
)
{
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOENT
;
if
(
!
drv
->
bdrv_snapshot_list
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_list
(
bs
,
psn_info
);
}
#define NB_SUFFIXES 4
char
*
get_human_readable_size
(
char
*
buf
,
int
buf_size
,
int64_t
size
)
{
static
const
char
suffixes
[
NB_SUFFIXES
]
=
"KMGT"
;
int64_t
base
;
int
i
;
if
(
size
<=
999
)
{
snprintf
(
buf
,
buf_size
,
"%"
PRId64
,
size
);
}
else
{
base
=
1024
;
for
(
i
=
0
;
i
<
NB_SUFFIXES
;
i
++
)
{
if
(
size
<
(
10
*
base
))
{
snprintf
(
buf
,
buf_size
,
"%0.1f%c"
,
(
double
)
size
/
base
,
suffixes
[
i
]);
break
;
}
else
if
(
size
<
(
1000
*
base
)
||
i
==
(
NB_SUFFIXES
-
1
))
{
snprintf
(
buf
,
buf_size
,
"%"
PRId64
"%c"
,
((
size
+
(
base
>>
1
))
/
base
),
suffixes
[
i
]);
break
;
}
base
=
base
*
1024
;
}
}
return
buf
;
}
char
*
bdrv_snapshot_dump
(
char
*
buf
,
int
buf_size
,
QEMUSnapshotInfo
*
sn
)
{
char
buf1
[
128
],
date_buf
[
128
],
clock_buf
[
128
];
struct
tm
tm
;
time_t
ti
;
int64_t
secs
;
if
(
!
sn
)
{
snprintf
(
buf
,
buf_size
,
"%-10s%-20s%7s%20s%15s"
,
"ID"
,
"TAG"
,
"VM SIZE"
,
"DATE"
,
"VM CLOCK"
);
}
else
{
ti
=
sn
->
date_sec
;
localtime_r
(
&
ti
,
&
tm
);
strftime
(
date_buf
,
sizeof
(
date_buf
),
"%Y-%m-%d %H:%M:%S"
,
&
tm
);
secs
=
sn
->
vm_clock_nsec
/
1000000000
;
snprintf
(
clock_buf
,
sizeof
(
clock_buf
),
"%02d:%02d:%02d.%03d"
,
(
int
)(
secs
/
3600
),
(
int
)((
secs
/
60
)
%
60
),
(
int
)(
secs
%
60
),
(
int
)((
sn
->
vm_clock_nsec
/
1000000
)
%
1000
));
snprintf
(
buf
,
buf_size
,
"%-10s%-20s%7s%20s%15s"
,
sn
->
id_str
,
sn
->
name
,
get_human_readable_size
(
buf1
,
sizeof
(
buf1
),
sn
->
vm_state_size
),
date_buf
,
clock_buf
);
}
return
buf
;
}
/**************************************************************/
/* async I/Os */
...
...
@@ -1108,4 +1235,5 @@ void bdrv_init(void)
bdrv_register
(
&
bdrv_bochs
);
bdrv_register
(
&
bdrv_vpc
);
bdrv_register
(
&
bdrv_vvfat
);
bdrv_register
(
&
bdrv_qcow2
);
}
block_int.h
View file @
faea38e7
...
...
@@ -57,6 +57,17 @@ struct BlockDriver {
const
uint8_t
*
buf
,
int
count
);
int
(
*
bdrv_truncate
)(
BlockDriverState
*
bs
,
int64_t
offset
);
int64_t
(
*
bdrv_getlength
)(
BlockDriverState
*
bs
);
int
(
*
bdrv_write_compressed
)(
BlockDriverState
*
bs
,
int64_t
sector_num
,
const
uint8_t
*
buf
,
int
nb_sectors
);
int
(
*
bdrv_snapshot_create
)(
BlockDriverState
*
bs
,
QEMUSnapshotInfo
*
sn_info
);
int
(
*
bdrv_snapshot_goto
)(
BlockDriverState
*
bs
,
const
char
*
snapshot_id
);
int
(
*
bdrv_snapshot_delete
)(
BlockDriverState
*
bs
,
const
char
*
snapshot_id
);
int
(
*
bdrv_snapshot_list
)(
BlockDriverState
*
bs
,
QEMUSnapshotInfo
**
psn_info
);
int
(
*
bdrv_get_info
)(
BlockDriverState
*
bs
,
BlockDriverInfo
*
bdi
);
struct
BlockDriver
*
next
;
};
...
...
monitor.c
View file @
faea38e7
...
...
@@ -380,18 +380,6 @@ static void do_log(const char *items)
cpu_set_log
(
mask
);
}
static
void
do_savevm
(
const
char
*
filename
)
{
if
(
qemu_savevm
(
filename
)
<
0
)
term_printf
(
"I/O error when saving VM to '%s'
\n
"
,
filename
);
}
static
void
do_loadvm
(
const
char
*
filename
)
{
if
(
qemu_loadvm
(
filename
)
<
0
)
term_printf
(
"I/O error when loading VM from '%s'
\n
"
,
filename
);
}
static
void
do_stop
(
void
)
{
vm_stop
(
EXCP_INTERRUPT
);
...
...
@@ -1155,10 +1143,12 @@ static term_cmd_t term_cmds[] = {
"filename"
,
"save screen into PPM image 'filename'"
},
{
"log"
,
"s"
,
do_log
,
"item1[,...]"
,
"activate logging of the specified items to '/tmp/qemu.log'"
},
{
"savevm"
,
"F"
,
do_savevm
,
"filename"
,
"save the whole virtual machine state to 'filename'"
},
{
"loadvm"
,
"F"
,
do_loadvm
,
"filename"
,
"restore the whole virtual machine state from 'filename'"
},
{
"savevm"
,
"s?"
,
do_savevm
,
"tag|id"
,
"save a VM snapshot. If no tag or id are provided, a new snapshot is created"
},
{
"loadvm"
,
"s"
,
do_loadvm
,
"tag|id"
,
"restore a VM snapshot from its tag or id"
},
{
"delvm"
,
"s"
,
do_delvm
,
"tag|id"
,
"delete a VM snapshot from its tag or id"
},
{
"stop"
,
""
,
do_stop
,
""
,
"stop emulation"
,
},
{
"c|cont"
,
""
,
do_cont
,
...
...
@@ -1241,6 +1231,8 @@ static term_cmd_t info_cmds[] = {
""
,
"show profiling information"
,
},
{
"capture"
,
""
,
do_info_capture
,
"show capture information"
},
{
"snapshots"
,
""
,
do_info_snapshots
,
"show the currently saved VM snapshots"
},
{
NULL
,
NULL
,
},
};
...
...
qemu-img.c
View file @
faea38e7
...
...
@@ -159,36 +159,6 @@ void help(void)
exit
(
1
);
}
#define NB_SUFFIXES 4
static
void
get_human_readable_size
(
char
*
buf
,
int
buf_size
,
int64_t
size
)
{
static
const
char
suffixes
[
NB_SUFFIXES
]
=
"KMGT"
;
int64_t
base
;
int
i
;
if
(
size
<=
999
)
{
snprintf
(
buf
,
buf_size
,
"%"
PRId64
,
size
);
}
else
{
base
=
1024
;
for
(
i
=
0
;
i
<
NB_SUFFIXES
;
i
++
)
{
if
(
size
<
(
10
*
base
))
{
snprintf
(
buf
,
buf_size
,
"%0.1f%c"
,
(
double
)
size
/
base
,
suffixes
[
i
]);
break
;
}
else
if
(
size
<
(
1000
*
base
)
||
i
==
(
NB_SUFFIXES
-
1
))
{
snprintf
(
buf
,
buf_size
,
"%"
PRId64
"%c"
,
((
size
+
(
base
>>
1
))
/
base
),
suffixes
[
i
]);
break
;
}
base
=
base
*
1024
;
}
}
}
#if defined(WIN32)
/* XXX: put correct support for win32 */
static
int
read_password
(
char
*
buf
,
int
buf_size
)
...
...
@@ -486,6 +456,7 @@ static int img_convert(int argc, char **argv)
int64_t
total_sectors
,
nb_sectors
,
sector_num
;
uint8_t
buf
[
IO_BUF_SIZE
];
const
uint8_t
*
buf1
;
BlockDriverInfo
bdi
;
fmt
=
NULL
;
out_fmt
=
"raw"
;
...
...
@@ -525,9 +496,9 @@ static int img_convert(int argc, char **argv)
drv
=
bdrv_find_format
(
out_fmt
);
if
(
!
drv
)
error
(
"Unknown file format '%s'"
,
fmt
);
if
(
compress
&&
drv
!=
&
bdrv_qcow
)
if
(
compress
&&
drv
!=
&
bdrv_qcow
&&
drv
!=
&
bdrv_qcow2
)
error
(
"Compression not supported for this file format"
);
if
(
encrypt
&&
drv
!=
&
bdrv_qcow
)
if
(
encrypt
&&
drv
!=
&
bdrv_qcow
&&
drv
!=
&
bdrv_qcow2
)
error
(
"Encryption not supported for this file format"
);
if
(
compress
&&
encrypt
)
error
(
"Compression and encryption not supported at the same time"
);
...
...
@@ -544,7 +515,9 @@ static int img_convert(int argc, char **argv)
out_bs
=
bdrv_new_open
(
out_filename
,
out_fmt
);
if
(
compress
)
{
cluster_size
=
qcow_get_cluster_size
(
out_bs
);
if
(
bdrv_get_info
(
out_bs
,
&
bdi
)
<
0
)
error
(
"could not get block driver info"
);
cluster_size
=
bdi
.
cluster_size
;
if
(
cluster_size
<=
0
||
cluster_size
>
IO_BUF_SIZE
)
error
(
"invalid cluster size"
);
cluster_sectors
=
cluster_size
>>
9
;
...
...
@@ -562,12 +535,15 @@ static int img_convert(int argc, char **argv)
if
(
n
<
cluster_sectors
)
memset
(
buf
+
n
*
512
,
0
,
cluster_size
-
n
*
512
);
if
(
is_not_zero
(
buf
,
cluster_size
))
{
if
(
qcow_compress_cluster
(
out_bs
,
sector_num
,
buf
)
!=
0
)
if
(
bdrv_write_compressed
(
out_bs
,
sector_num
,
buf
,
cluster_sectors
)
!=
0
)
error
(
"error while compressing sector %"
PRId64
,
sector_num
);
}
sector_num
+=
n
;
}
/* signal EOF to align */
bdrv_write_compressed
(
out_bs
,
0
,
NULL
,
0
);
}
else
{
sector_num
=
0
;
for
(;;)
{
...
...
@@ -630,6 +606,24 @@ static int64_t get_allocated_file_size(const char *filename)
}
#endif
static
void
dump_snapshots
(
BlockDriverState
*
bs
)
{
QEMUSnapshotInfo
*
sn_tab
,
*
sn
;
int
nb_sns
,
i
;
char
buf
[
256
];
nb_sns
=
bdrv_snapshot_list
(
bs
,
&
sn_tab
);
if
(
nb_sns
<=
0
)
return
;
printf
(
"Snapshot list:
\n
"
);
printf
(
"%s
\n
"
,
bdrv_snapshot_dump
(
buf
,
sizeof
(
buf
),
NULL
));
for
(
i
=
0
;
i
<
nb_sns
;
i
++
)
{
sn
=
&
sn_tab
[
i
];
printf
(
"%s
\n
"
,
bdrv_snapshot_dump
(
buf
,
sizeof
(
buf
),
sn
));
}
qemu_free
(
sn_tab
);
}
static
int
img_info
(
int
argc
,
char
**
argv
)
{
int
c
;
...
...
@@ -640,6 +634,7 @@ static int img_info(int argc, char **argv)
int64_t
total_sectors
,
allocated_size
;
char
backing_filename
[
1024
];
char
backing_filename2
[
1024
];
BlockDriverInfo
bdi
;
fmt
=
NULL
;
for
(;;)
{
...
...
@@ -690,13 +685,19 @@ static int img_info(int argc, char **argv)
dsize_buf
);
if
(
bdrv_is_encrypted
(
bs
))
printf
(
"encrypted: yes
\n
"
);
if
(
bdrv_get_info
(
bs
,
&
bdi
)
>=
0
)
{
if
(
bdi
.
cluster_size
!=
0
)
printf
(
"cluster_size: %d
\n
"
,
bdi
.
cluster_size
);
}
bdrv_get_backing_filename
(
bs
,
backing_filename
,
sizeof
(
backing_filename
));
if
(
backing_filename
[
0
]
!=
'\0'
)
if
(
backing_filename
[
0
]
!=
'\0'
)
{
path_combine
(
backing_filename2
,
sizeof
(
backing_filename2
),
filename
,
backing_filename
);
printf
(
"backing file: %s (actual path: %s)
\n
"
,
backing_filename
,
backing_filename2
);
}
dump_snapshots
(
bs
);
bdrv_delete
(
bs
);
return
0
;
}
...
...
vl.c
View file @
faea38e7
...
...
@@ -113,7 +113,11 @@ char phys_ram_file[1024];
void
*
ioport_opaque
[
MAX_IOPORTS
];
IOPortReadFunc
*
ioport_read_table
[
3
][
MAX_IOPORTS
];
IOPortWriteFunc
*
ioport_write_table
[
3
][
MAX_IOPORTS
];
BlockDriverState
*
bs_table
[
MAX_DISKS
],
*
fd_table
[
MAX_FD
];
/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
to store the VM snapshots */
BlockDriverState
*
bs_table
[
MAX_DISKS
+
1
],
*
fd_table
[
MAX_FD
];
/* point to the block driver where the snapshots are managed */
BlockDriverState
*
bs_snapshots
;
int
vga_ram_size
;
int
bios_size
;
static
DisplayState
display_state
;
...
...
@@ -4085,14 +4089,190 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
/***********************************************************/
/* savevm/loadvm support */
#define IO_BUF_SIZE 32768
struct
QEMUFile
{
FILE
*
outfile
;
BlockDriverState
*
bs
;
int
is_file
;
int
is_writable
;
int64_t
base_offset
;
int64_t
buf_offset
;
/* start of buffer when writing, end of buffer
when reading */
int
buf_index
;
int
buf_size
;
/* 0 when writing */
uint8_t
buf
[
IO_BUF_SIZE
];
};
QEMUFile
*
qemu_fopen
(
const
char
*
filename
,
const
char
*
mode
)
{
QEMUFile
*
f
;
f
=
qemu_mallocz
(
sizeof
(
QEMUFile
));
if
(
!
f
)
return
NULL
;
if
(
!
strcmp
(
mode
,
"wb"
))
{
f
->
is_writable
=
1
;
}
else
if
(
!
strcmp
(
mode
,
"rb"
))
{
f
->
is_writable
=
0
;
}
else
{
goto
fail
;
}
f
->
outfile
=
fopen
(
filename
,
mode
);
if
(
!
f
->
outfile
)
goto
fail
;
f
->
is_file
=
1
;
return
f
;
fail:
if
(
f
->
outfile
)
fclose
(
f
->
outfile
);
qemu_free
(
f
);
return
NULL
;
}
QEMUFile
*
qemu_fopen_bdrv
(
BlockDriverState
*
bs
,
int64_t
offset
,
int
is_writable
)
{
QEMUFile
*
f
;
f
=
qemu_mallocz
(
sizeof
(
QEMUFile
));
if
(
!
f
)
return
NULL
;
f
->
is_file
=
0
;
f
->
bs
=
bs
;
f
->
is_writable
=
is_writable
;
f
->
base_offset
=
offset
;
return
f
;
}
void
qemu_fflush
(
QEMUFile
*
f
)
{
if
(
!
f
->
is_writable
)
return
;
if
(
f
->
buf_index
>
0
)
{
if
(
f
->
is_file
)
{
fseek
(
f
->
outfile
,
f
->
buf_offset
,
SEEK_SET
);
fwrite
(
f
->
buf
,
1
,
f
->
buf_index
,
f
->
outfile
);
}
else
{
bdrv_pwrite
(
f
->
bs
,
f
->
base_offset
+
f
->
buf_offset
,
f
->
buf
,
f
->
buf_index
);
}
f
->
buf_offset
+=
f
->
buf_index
;
f
->
buf_index
=
0
;
}
}
static
void
qemu_fill_buffer
(
QEMUFile
*
f
)
{
int
len
;
if
(
f
->
is_writable
)
return
;
if
(
f
->
is_file
)
{
fseek
(
f
->
outfile
,
f
->
buf_offset
,
SEEK_SET
);
len
=
fread
(
f
->
buf
,
1
,
IO_BUF_SIZE
,
f
->
outfile
);
if
(
len
<
0
)
len
=
0
;
}
else
{
len
=
bdrv_pread
(
f
->
bs
,
f
->
base_offset
+
f
->
buf_offset
,
f
->
buf
,
IO_BUF_SIZE
);
if
(
len
<
0
)
len
=
0
;
}
f
->
buf_index
=
0
;
f
->
buf_size
=
len
;
f
->
buf_offset
+=
len
;
}
void
qemu_fclose
(
QEMUFile
*
f
)
{
if
(
f
->
is_writable
)
qemu_fflush
(
f
);
if
(
f
->
is_file
)
{
fclose
(
f
->
outfile
);
}
qemu_free
(
f
);
}
void
qemu_put_buffer
(
QEMUFile
*
f
,
const
uint8_t
*
buf
,
int
size
)
{
fwrite
(
buf
,
1
,
size
,
f
);
int
l
;
while
(
size
>
0
)
{
l
=
IO_BUF_SIZE
-
f
->
buf_index
;
if
(
l
>
size
)
l
=
size
;
memcpy
(
f
->
buf
+
f
->
buf_index
,
buf
,
l
);
f
->
buf_index
+=
l
;
buf
+=
l
;
size
-=
l
;
if
(
f
->
buf_index
>=
IO_BUF_SIZE
)
qemu_fflush
(
f
);
}
}
void
qemu_put_byte
(
QEMUFile
*
f
,
int
v
)
{
fputc
(
v
,
f
);
f
->
buf
[
f
->
buf_index
++
]
=
v
;
if
(
f
->
buf_index
>=
IO_BUF_SIZE
)
qemu_fflush
(
f
);
}
int
qemu_get_buffer
(
QEMUFile
*
f
,
uint8_t
*
buf
,
int
size1
)
{
int
size
,
l
;
size
=
size1
;
while
(
size
>
0
)
{
l
=
f
->
buf_size
-
f
->
buf_index
;
if
(
l
==
0
)
{
qemu_fill_buffer
(
f
);
l
=
f
->
buf_size
-
f
->
buf_index
;
if
(
l
==
0
)
break
;
}
if
(
l
>
size
)
l
=
size
;
memcpy
(
buf
,
f
->
buf
+
f
->
buf_index
,
l
);
f
->
buf_index
+=
l
;
buf
+=
l
;
size
-=
l
;
}
return
size1
-
size
;
}
int
qemu_get_byte
(
QEMUFile
*
f
)
{
if
(
f
->
buf_index
>=
f
->
buf_size
)
{
qemu_fill_buffer
(
f
);
if
(
f
->
buf_index
>=
f
->
buf_size
)
return
0
;
}
return
f
->
buf
[
f
->
buf_index
++
];
}
int64_t
qemu_ftell
(
QEMUFile
*
f
)
{
return
f
->
buf_offset
-
f
->
buf_size
+
f
->
buf_index
;
}
int64_t
qemu_fseek
(
QEMUFile
*
f
,
int64_t
pos
,
int
whence
)
{
if
(
whence
==
SEEK_SET
)
{
/* nothing to do */
}
else
if
(
whence
==
SEEK_CUR
)
{
pos
+=
qemu_ftell
(
f
);
}
else
{
/* SEEK_END not supported */
return
-
1
;
}
if
(
f
->
is_writable
)
{
qemu_fflush
(
f
);
f
->
buf_offset
=
pos
;
}
else
{
f
->
buf_offset
=
pos
;
f
->
buf_index
=
0
;
f
->
buf_size
=
0
;
}
return
pos
;
}
void
qemu_put_be16
(
QEMUFile
*
f
,
unsigned
int
v
)
...
...
@@ -4115,21 +4295,6 @@ void qemu_put_be64(QEMUFile *f, uint64_t v)
qemu_put_be32
(
f
,
v
);
}
int
qemu_get_buffer
(
QEMUFile
*
f
,
uint8_t
*
buf
,
int
size
)
{
return
fread
(
buf
,
1
,
size
,
f
);
}
int
qemu_get_byte
(
QEMUFile
*
f
)
{
int
v
;
v
=
fgetc
(
f
);
if
(
v
==
EOF
)
return
0
;
else
return
v
;
}
unsigned
int
qemu_get_be16
(
QEMUFile
*
f
)
{
unsigned
int
v
;
...
...
@@ -4156,18 +4321,6 @@ uint64_t qemu_get_be64(QEMUFile *f)
return
v
;
}
int64_t
qemu_ftell
(
QEMUFile
*
f
)
{
return
ftell
(
f
);
}
int64_t
qemu_fseek
(
QEMUFile
*
f
,
int64_t
pos
,
int
whence
)
{