37 #include <sys/types.h>
49 #include "debug/DiskImageRead.hh"
50 #include "debug/DiskImageWrite.hh"
62 {
open(p->image_file, p->read_only); }
71 panic(
"Attempting to fork system with read-write raw disk image.");
75 open(p->image_file, p->read_only);
81 if (!filename.empty()) {
86 ios::openmode
mode = ios::in | ios::binary;
91 panic(
"Error opening %s", filename);
106 panic(
"file not open!\n");
107 stream.seekg(0, ios::end);
118 panic(
"RawDiskImage not initialized");
121 panic(
"file not open!\n");
125 panic(
"Could not seek to location in file");
127 streampos pos =
stream.tellg();
128 stream.read((
char *)data, SectorSize);
130 DPRINTF(DiskImageRead,
"read: offset=%d\n", (uint64_t)offset);
131 DDUMP(DiskImageRead, data, SectorSize);
133 return stream.tellg() - pos;
140 panic(
"RawDiskImage not initialized");
143 panic(
"Cannot write to a read only disk image");
146 panic(
"file not open!\n");
150 panic(
"Could not seek to location in file");
152 DPRINTF(DiskImageWrite,
"write: offset=%d\n", (uint64_t)offset);
153 DDUMP(DiskImageWrite, data, SectorSize);
155 streampos pos =
stream.tellp();
156 stream.write((
const char *)data, SectorSize);
157 return stream.tellp() - pos;
161 RawDiskImageParams::create()
184 :
DiskImage(p), filename(p->image_file), child(p->child), table(NULL)
191 fatal(
"could not open read-only file");
202 SectorTable::iterator
i =
table->begin();
203 SectorTable::iterator end =
table->end();
214 if (!dynamic_cast<const Params *>(
params())->read_only &&
216 inform(
"Disabling saving of COW image in forked child process.\n");
224 stream.read((
char *)data, count);
225 if (!stream.is_open())
226 panic(
"file not open");
229 panic(
"premature end-of-file");
231 if (stream.bad() || stream.fail())
232 panic(
"error reading cowdisk image");
239 SafeRead(stream, &data,
sizeof(data));
246 SafeRead(stream, &data,
sizeof(data));
253 ifstream stream(file.c_str());
254 if (!stream.is_open())
257 if (stream.fail() || stream.bad())
258 panic(
"Error opening %s", file);
263 if (memcmp(&magic,
"COWDISK!",
sizeof(magic)) != 0)
264 panic(
"Could not open %s: Invalid magic", file);
266 uint32_t major, minor;
271 panic(
"Could not open %s: invalid version %d.%d != %d.%d",
274 uint64_t sector_count;
279 for (uint64_t
i = 0;
i < sector_count;
i++) {
287 (*table)[
offset] = sector;
307 stream.write((
const char *)data, count);
308 if (!stream.is_open())
309 panic(
"file not open");
312 panic(
"premature end-of-file");
314 if (stream.bad() || stream.fail())
315 panic(
"error reading cowdisk image");
329 T swappeddata =
letoh(data);
330 SafeWrite(stream, &swappeddata,
sizeof(data));
346 panic(
"RawDiskImage not initialized");
348 ofstream stream(file.c_str());
349 if (!stream.is_open() || stream.fail() || stream.bad())
350 panic(
"Error opening %s", file);
353 memcpy(&magic,
"COWDISK!",
sizeof(magic));
361 SectorTable::iterator iter =
table->begin();
362 SectorTable::iterator end =
table->end();
364 for (uint64_t
i = 0;
i <
size;
i++) {
366 panic(
"Incorrect Table Size during save of COW disk image");
369 SafeWrite(stream, (*iter).second->data,
sizeof(Sector));
379 SectorTable::iterator
i =
table->begin();
380 SectorTable::iterator end =
table->end();
396 panic(
"CowDiskImage not initialized");
399 panic(
"access out of bounds");
401 SectorTable::const_iterator
i =
table->find(offset);
402 if (i ==
table->end())
406 DPRINTF(DiskImageRead,
"read: offset=%d\n", (uint64_t)offset);
416 panic(
"RawDiskImage not initialized");
419 panic(
"access out of bounds");
421 SectorTable::iterator
i =
table->find(offset);
422 if (i ==
table->end()) {
425 table->insert(make_pair(offset, sector));
430 DPRINTF(DiskImageWrite,
"write: offset=%d\n", (uint64_t)offset);
439 string cowFilename =
name() +
".cow";
449 cowFilename = cp.
cptDir +
"/" + cowFilename;
454 CowDiskImageParams::create()
std::streampos write(const uint8_t *data, std::streampos offset) override
std::streampos size() const override
CowDiskImage(const Params *p)
std::streampos read(uint8_t *data, std::streampos offset) const override
#define DDUMP(x, data, count)
const Params * params() const
std::streampos size() const override
void SafeReadSwap(ifstream &stream, T &data)
Specialization for accessing a copy-on-write disk image layer.
static const uint32_t VersionMinor
void SafeWrite(ofstream &stream, const void *data, int count)
void serialize(CheckpointOut &cp) const override
Serialize an object.
void notifyFork() override
Notify a child process of a fork.
virtual std::streampos size() const =0
#define UNSERIALIZE_SCALAR(scalar)
std::unordered_map< uint64_t, Sector * > SectorTable
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
void registerExitCallback(Callback *callback)
Register an exit callback.
void SafeRead(ifstream &stream, void *data, int count)
Basic interface for accessing a disk image.
void open(const std::string &filename, bool rd_only=false)
#define SERIALIZE_SCALAR(scalar)
RawDiskImage(const Params *p)
static const uint32_t VersionMajor
virtual const std::string name() const
void SafeWriteSwap(ofstream &stream, const T &data)
std::ostream CheckpointOut
std::streampos read(uint8_t *data, std::streampos offset) const override
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
std::streampos write(const uint8_t *data, std::streampos offset) override
void initSectorTable(int hash_size)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool open(const std::string &file)
Specialization for accessing a raw disk image.
void process()
virtual process function that is invoked when the callback queue is executed.
CowDiskCallback(CowDiskImage *i)
void notifyFork() override
Notify a child process of a fork.