35 #include <sys/types.h> 47 #include "debug/DiskImageRead.hh" 48 #include "debug/DiskImageWrite.hh" 60 {
open(p->image_file, p->read_only); }
69 panic(
"Attempting to fork system with read-write raw disk image.");
73 open(p->image_file, p->read_only);
79 if (!filename.empty()) {
84 ios::openmode
mode = ios::in | ios::binary;
89 panic(
"Error opening %s", filename);
104 panic(
"file not open!\n");
105 stream.seekg(0, ios::end);
116 panic(
"RawDiskImage not initialized");
119 panic(
"file not open!\n");
123 panic(
"Could not seek to location in file");
125 streampos pos =
stream.tellg();
126 stream.read((
char *)data, SectorSize);
128 DPRINTF(DiskImageRead,
"read: offset=%d\n", (uint64_t)offset);
129 DDUMP(DiskImageRead, data, SectorSize);
131 return stream.tellg() - pos;
138 panic(
"RawDiskImage not initialized");
141 panic(
"Cannot write to a read only disk image");
144 panic(
"file not open!\n");
148 panic(
"Could not seek to location in file");
150 DPRINTF(DiskImageWrite,
"write: offset=%d\n", (uint64_t)offset);
151 DDUMP(DiskImageWrite, data, SectorSize);
153 streampos pos =
stream.tellp();
154 stream.write((
const char *)data, SectorSize);
155 return stream.tellp() - pos;
159 RawDiskImageParams::create()
189 fatal(
"could not open read-only file");
200 SectorTable::iterator
i =
table->begin();
201 SectorTable::iterator end =
table->end();
212 if (!dynamic_cast<const Params *>(
params())->read_only &&
214 inform(
"Disabling saving of COW image in forked child process.\n");
222 stream.read((
char *)data, count);
223 if (!stream.is_open())
224 panic(
"file not open");
227 panic(
"premature end-of-file");
229 if (stream.bad() || stream.fail())
230 panic(
"error reading cowdisk image");
237 SafeRead(stream, &data,
sizeof(data));
244 SafeRead(stream, &data,
sizeof(data));
251 ifstream stream(file.c_str());
252 if (!stream.is_open())
255 if (stream.fail() || stream.bad())
256 panic(
"Error opening %s", file);
261 if (memcmp(&magic,
"COWDISK!",
sizeof(magic)) != 0)
262 panic(
"Could not open %s: Invalid magic", file);
264 uint32_t major, minor;
269 panic(
"Could not open %s: invalid version %d.%d != %d.%d",
272 uint64_t sector_count;
277 for (uint64_t
i = 0;
i < sector_count;
i++) {
285 (*table)[
offset] = sector;
305 stream.write((
const char *)data, count);
306 if (!stream.is_open())
307 panic(
"file not open");
310 panic(
"premature end-of-file");
312 if (stream.bad() || stream.fail())
313 panic(
"error reading cowdisk image");
327 T swappeddata =
letoh(data);
328 SafeWrite(stream, &swappeddata,
sizeof(data));
344 panic(
"RawDiskImage not initialized");
346 ofstream stream(file.c_str());
347 if (!stream.is_open() || stream.fail() || stream.bad())
348 panic(
"Error opening %s", file);
351 memcpy(&magic,
"COWDISK!",
sizeof(magic));
359 SectorTable::iterator iter =
table->begin();
360 SectorTable::iterator end =
table->end();
362 for (uint64_t
i = 0;
i <
size;
i++) {
364 panic(
"Incorrect Table Size during save of COW disk image");
377 SectorTable::iterator
i =
table->begin();
378 SectorTable::iterator end =
table->end();
394 panic(
"CowDiskImage not initialized");
397 panic(
"access out of bounds");
399 SectorTable::const_iterator
i =
table->find(offset);
400 if (i ==
table->end())
404 DPRINTF(DiskImageRead,
"read: offset=%d\n", (uint64_t)offset);
414 panic(
"RawDiskImage not initialized");
417 panic(
"access out of bounds");
419 SectorTable::iterator
i =
table->find(offset);
420 if (i ==
table->end()) {
423 table->insert(make_pair(offset, sector));
428 DPRINTF(DiskImageWrite,
"write: offset=%d\n", (uint64_t)offset);
437 string cowFilename =
name() +
".cow";
447 cowFilename = cp.
getCptDir() +
"/" + cowFilename;
452 CowDiskImageParams::create()
std::streampos write(const uint8_t *data, std::streampos offset) override
#define panic(...)
This implements a cprintf based panic() function.
std::streampos size() const override
#define fatal(...)
This implements a cprintf based fatal() function.
CowDiskImage(const Params *p)
std::streampos read(uint8_t *data, std::streampos offset) const override
#define DDUMP(x, data, count)
std::streampos size() const override
void SafeReadSwap(ifstream &stream, T &data)
Overload hash function for BasicBlockRange type.
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.
const Params * params() const
void open(const std::string &filename, bool rd_only=false)
#define SERIALIZE_SCALAR(scalar)
RawDiskImage(const Params *p)
static std::string dir()
Get the current checkout directory name.
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
const uint8_t image_file[]
This image file contains the text "This is a test image.\n" 31 times.
const std::string getCptDir()
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.