- implemented save state function for redolog_t based disk image modes (growing,

undoable, volatile)
- TODO: save state function for the remaining image modes, restore support
- save/restore: when saving binary data to a file, use the full parameter path
  (except "bochs." prefix) as the file name to avoid overwriting duplicates
This commit is contained in:
Volker Ruppert 2012-09-17 19:30:40 +00:00
parent 6682d019e3
commit 7da5057be5
3 changed files with 80 additions and 41 deletions

View File

@ -1272,7 +1272,7 @@ bx_bool bx_real_sim_c::save_sr_param(FILE *fp, bx_param_c *node, const char *sr_
{
int i;
Bit64s value;
char tmpstr[BX_PATHNAME_LEN], tmpbyte[4];
char pname[BX_PATHNAME_LEN], tmpstr[BX_PATHNAME_LEN], tmpbyte[4];
FILE *fp2;
for (i=0; i<level; i++)
@ -1332,11 +1332,15 @@ bx_bool bx_real_sim_c::save_sr_param(FILE *fp, bx_param_c *node, const char *sr_
}
break;
case BXT_PARAM_DATA:
fprintf(fp, "%s.%s\n", node->get_parent()->get_name(), node->get_name());
node->get_param_path(pname, BX_PATHNAME_LEN);
if (!strncmp(pname, "bochs.", 6)) {
strcpy(pname, pname+6);
}
fprintf(fp, "%s\n", pname);
if (sr_path)
sprintf(tmpstr, "%s/%s.%s", sr_path, node->get_parent()->get_name(), node->get_name());
sprintf(tmpstr, "%s/%s", sr_path, pname);
else
sprintf(tmpstr, "%s.%s", node->get_parent()->get_name(), node->get_name());
strcpy(tmpstr, pname);
fp2 = fopen(tmpstr, "wb");
if (fp2 != NULL) {
fwrite(((bx_shadow_data_c*)node)->getptr(), 1, ((bx_shadow_data_c*)node)->get_size(), fp2);

View File

@ -168,6 +168,46 @@ Bit64s hdimage_save_handler(void *class_ptr, bx_param_c *param)
return ((device_image_t*)class_ptr)->save_state(path);
}
bx_bool hdimage_backup_file(int fd, const char *backup_fname)
{
char *buf;
off_t offset;
int nread, size;
bx_bool ret = 1;
int backup_fd = ::open(backup_fname, O_RDWR | O_CREAT | O_TRUNC
#ifdef O_BINARY
| O_BINARY
#endif
, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP);
if (backup_fd >= 0) {
offset = 0;
size = 0x20000;
buf = (char*)malloc(size);
if (buf == NULL) {
::close(backup_fd);
return 0;
}
while ((nread = bx_read_image(fd, offset, buf, size)) > 0) {
if (bx_write_image(backup_fd, offset, buf, nread) < 0) {
ret = 0;
break;
}
if (nread < size) {
break;
}
offset += size;
};
if (nread < 0) {
ret = 0;
}
free(buf);
::close(backup_fd);
return ret;
}
return 0;
}
/*** base class device_image_t ***/
device_image_t::device_image_t()
@ -275,43 +315,7 @@ Bit32u default_image_t::get_timestamp()
bx_bool default_image_t::save_state(const char *backup_fname)
{
char *buf;
off_t offset;
Bit32u size;
bx_bool ret = 1;
int backup_fd = ::open(backup_fname, O_RDWR | O_CREAT | O_TRUNC
#ifdef O_BINARY
| O_BINARY
#endif
, S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP);
if (backup_fd >= 0) {
offset = 0;
size = 0x20000;
buf = (char*)malloc(size);
if (buf == NULL) {
::close(backup_fd);
return 0;
}
while (offset < (off_t)hd_size) {
if (bx_read_image(fd, offset, buf, size) < 0) {
ret = 0;
break;
}
if (bx_write_image(backup_fd, offset, buf, size) < 0) {
ret = 0;
break;
}
offset += size;
if ((hd_size - offset) < size) {
size = hd_size - offset;
}
};
free(buf);
::close(backup_fd);
return ret;
}
return 0;
return hdimage_backup_file(fd, backup_fname);
}
// helper function for concat and sparse mode images
@ -1472,6 +1476,11 @@ ssize_t redolog_t::write(const void* buf, size_t count)
return written;
}
bx_bool redolog_t::save_state(const char *backup_fname)
{
return hdimage_backup_file(fd, backup_fname);
}
/*** growing_image_t function definitions ***/
growing_image_t::growing_image_t()
@ -1529,6 +1538,11 @@ ssize_t growing_image_t::write(const void* buf, size_t count)
return (ret < 0) ? ret : count;
}
bx_bool growing_image_t::save_state(const char *backup_fname)
{
return redolog->save_state(backup_fname);
}
/*** undoable_image_t function definitions ***/
undoable_image_t::undoable_image_t(const char* _redolog_name)
@ -1644,6 +1658,11 @@ ssize_t undoable_image_t::write(const void* buf, size_t count)
return (ret < 0) ? ret : count;
}
bx_bool undoable_image_t::save_state(const char *backup_fname)
{
return redolog->save_state(backup_fname);
}
/*** volatile_image_t function definitions ***/
volatile_image_t::volatile_image_t(const char* _redolog_name)
@ -1761,3 +1780,8 @@ ssize_t volatile_image_t::write(const void* buf, size_t count)
}
return (ret < 0) ? ret : count;
}
bx_bool volatile_image_t::save_state(const char *backup_fname)
{
return redolog->save_state(backup_fname);
}

View File

@ -374,6 +374,8 @@ class redolog_t
ssize_t read(void* buf, size_t count);
ssize_t write(const void* buf, size_t count);
bx_bool save_state(const char *backup_fname);
private:
void print_header();
int fd;
@ -417,6 +419,9 @@ class growing_image_t : public device_image_t
// written (count).
ssize_t write(const void* buf, size_t count);
// Save/restore support
bx_bool save_state(const char *backup_fname);
private:
redolog_t *redolog;
};
@ -447,6 +452,9 @@ class undoable_image_t : public device_image_t
// written (count).
ssize_t write(const void* buf, size_t count);
// Save/restore support
bx_bool save_state(const char *backup_fname);
private:
redolog_t *redolog; // Redolog instance
default_image_t *ro_disk; // Read-only flat disk instance
@ -480,6 +488,9 @@ class volatile_image_t : public device_image_t
// written (count).
ssize_t write(const void* buf, size_t count);
// Save/restore support
bx_bool save_state(const char *backup_fname);
private:
redolog_t *redolog; // Redolog instance
default_image_t *ro_disk; // Read-only flat disk instance