Tom Rollet has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/46619 )
Change subject: sim: Add serialization for host backed files
......................................................................
sim: Add serialization for host backed files
Change-Id: I4d0c7cd614a8abaffcae9aba1a28c9fdbc023c5a
---
M src/sim/fd_array.cc
M src/sim/fd_array.hh
M src/sim/fd_entry.cc
M src/sim/fd_entry.hh
M src/sim/process.cc
M src/sim/syscall_emul.hh
6 files changed, 132 insertions(+), 18 deletions(-)
diff --git a/src/sim/fd_array.cc b/src/sim/fd_array.cc
index 364bd10..d0eb9e0 100644
--- a/src/sim/fd_array.cc
+++ b/src/sim/fd_array.cc
@@ -348,3 +348,84 @@
return status;
}
+
+void
+FDArray::serialize(CheckpointOut &cp) const {
+ ScopedCheckpointSection sec(cp, "fdarray");
+ paramOut(cp, "size", _fdArray.size());
+ for (int tgt_fd = 0; tgt_fd < _fdArray.size(); tgt_fd++) {
+ auto fd = _fdArray[tgt_fd];
+ ScopedCheckpointSection sec(cp, csprintf("Entry%d", tgt_fd));
+ if (!fd) {
+ paramOut(cp, "class", FDEntry::FDClass::fd_null);
+ continue;
+ }
+ paramOut(cp, "class", fd->getClass());
+ fd->serialize(cp);
+ }
+}
+
+void
+FDArray::unserialize(CheckpointIn &cp) {
+ ScopedCheckpointSection sec(cp, "fdarray");
+ uint64_t size;
+ paramIn(cp, "size", size);
+ assert(_fdArray.size() == size &&
+ "FDArray sizes do not match at unserialize!");
+
+ for (int tgt_fd = 0; tgt_fd < _fdArray.size(); tgt_fd++) {
+ if (tgt_fd == STDIN_FILENO || tgt_fd == STDOUT_FILENO ||
+ tgt_fd == STDERR_FILENO)
+ continue;
+ ScopedCheckpointSection sec(cp, csprintf("Entry%d", tgt_fd));
+ FDEntry::FDClass fd_class;
+ paramIn(cp, "class", fd_class);
+ std::shared_ptr<FDEntry> fdep;
+
+ switch (fd_class) {
+ case FDEntry::FDClass::fd_base:
+ panic("Abstract fd entry was serialized");
+ break;
+ case FDEntry::FDClass::fd_hb:
+ fdep = std::make_shared<HBFDEntry>(0, 0);
+ break;
+ case FDEntry::FDClass::fd_file:
+ fdep = std::make_shared<FileFDEntry>(0, 0, "", 0, 00);
+ break;
+ case FDEntry::FDClass::fd_device:
+ fdep = std::make_shared<DeviceFDEntry>(nullptr, "");
+ break;
+ case FDEntry::FDClass::fd_pipe:
+ fdep = std::make_shared<PipeFDEntry>(
+ 0, 0, PipeFDEntry::EndType::read);
+ break;
+ case FDEntry::FDClass::fd_socket:
+ fdep = std::make_shared<SocketFDEntry>(0, 0, 0, 0);
+ break;
+ case FDEntry::FDClass::fd_null:
+ continue;
+ default:
+ panic("Unrecognized fd class");
+ break;
+ }
+
+ fdep->unserialize(cp);
+
+ auto this_ffd = std::dynamic_pointer_cast<FileFDEntry>(fdep);
+ if (!this_ffd)
+ continue;
+ setFDEntry(tgt_fd, fdep);
+
+ mode_t mode = this_ffd->getFileMode();
+ std::string const& path = this_ffd->getFileName();
+ int flags = this_ffd->getFlags();
+
+ // Re-open the file and assign a new sim_fd
+ int sim_fd = openFile(path, flags, mode);
+ this_ffd->setSimFD(sim_fd);
+
+ // Restore the file offset to the proper value
+ uint64_t file_offset = this_ffd->getFileOffset();
+ lseek(sim_fd, file_offset, SEEK_SET);
+ }
+}
diff --git a/src/sim/fd_array.hh b/src/sim/fd_array.hh
index 5295566..e80673f 100644
--- a/src/sim/fd_array.hh
+++ b/src/sim/fd_array.hh
@@ -40,8 +40,9 @@
#include <string>
#include "sim/fd_entry.hh"
+#include "sim/serialize.hh"
-class FDArray
+class FDArray : public Serializable
{
public:
/**
@@ -111,6 +112,12 @@
*/
int closeFDEntry(int tgt_fd);
+ /*
+ * Serialization methods for file descriptors
+ */
+ void serialize(CheckpointOut &cp) const override;
+ void unserialize(CheckpointIn &cp) override;
+
private:
/**
* Help clarify our intention when opening files in the init and
diff --git a/src/sim/fd_entry.cc b/src/sim/fd_entry.cc
index 02677d6..6861a94 100644
--- a/src/sim/fd_entry.cc
+++ b/src/sim/fd_entry.cc
@@ -54,6 +54,7 @@
SERIALIZE_SCALAR(_flags);
SERIALIZE_SCALAR(_fileName);
SERIALIZE_SCALAR(_fileOffset);
+ SERIALIZE_SCALAR(_mode);
}
void
@@ -63,6 +64,7 @@
UNSERIALIZE_SCALAR(_flags);
UNSERIALIZE_SCALAR(_fileName);
UNSERIALIZE_SCALAR(_fileOffset);
+ UNSERIALIZE_SCALAR(_mode);
}
void
diff --git a/src/sim/fd_entry.hh b/src/sim/fd_entry.hh
index c24710d..50a9e60 100644
--- a/src/sim/fd_entry.hh
+++ b/src/sim/fd_entry.hh
@@ -42,6 +42,7 @@
class EmulatedDriver;
+
/**
* Holds a single file descriptor mapping and that mapping's data for
* processes running in syscall emulation mode.
@@ -49,14 +50,28 @@
class FDEntry : public Serializable
{
public:
+
+ enum FDClass
+ {
+ fd_base,
+ fd_hb,
+ fd_file,
+ fd_pipe,
+ fd_device,
+ fd_socket,
+ fd_null
+ };
+
FDEntry(bool close_on_exec = false)
: _closeOnExec(close_on_exec)
- { }
+ { _class = FDClass::fd_base; }
virtual std::shared_ptr<FDEntry> clone() const = 0;
bool getCOE() const { return _closeOnExec; }
+ FDClass getClass() const { return _class; }
+
void setCOE(bool close_on_exec) { _closeOnExec = close_on_exec; }
virtual void serialize(CheckpointOut &cp) const;
@@ -64,6 +79,7 @@
protected:
bool _closeOnExec;
+ FDClass _class;
};
/**
@@ -76,11 +92,11 @@
public:
HBFDEntry(int flags, int sim_fd, bool close_on_exec = false)
: FDEntry(close_on_exec), _flags(flags), _simFD(sim_fd)
- { }
+ { _class = FDClass::fd_hb; }
HBFDEntry(HBFDEntry const& reg, bool close_on_exec = false)
: FDEntry(close_on_exec), _flags(reg._flags), _simFD(reg._simFD)
- { }
+ { _class = FDClass::fd_hb; }
std::shared_ptr<FDEntry>
clone() const override
@@ -114,12 +130,12 @@
uint64_t file_offset, bool close_on_exec = false)
: HBFDEntry(flags, sim_fd, close_on_exec),
_fileName(file_name), _fileOffset(file_offset)
- { }
+ { _class = FDClass::fd_file; }
FileFDEntry(FileFDEntry const& reg, bool close_on_exec = false)
: HBFDEntry(reg._flags, reg._simFD, close_on_exec),
_fileName(reg._fileName), _fileOffset(reg._fileOffset)
- { }
+ { _class = FDClass::fd_file; }
std::shared_ptr<FDEntry>
clone() const override
@@ -129,9 +145,11 @@
std::string const& getFileName() const { return _fileName; }
uint64_t getFileOffset() const { return _fileOffset; }
+ mode_t getFileMode() const { return _mode; }
void setFileName(std::string const& file_name) { _fileName =
file_name; }
void setFileOffset(uint64_t f_off) { _fileOffset = f_off; }
+ void setFileMode(mode_t mode) { _mode = mode; }
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
@@ -139,6 +157,7 @@
private:
std::string _fileName;
uint64_t _fileOffset;
+ mode_t _mode;
};
/**
@@ -158,13 +177,13 @@
bool close_on_exec = false)
: HBFDEntry(flags, sim_fd, close_on_exec), _pipeReadSource(-1),
_pipeEndType(pipe_end_type)
- { }
+ { _class = FDClass::fd_pipe; }
PipeFDEntry(PipeFDEntry const& pipe, bool close_on_exec = false)
: HBFDEntry(pipe._flags, pipe._simFD, close_on_exec),
_pipeReadSource(pipe._pipeReadSource),
_pipeEndType(pipe._pipeEndType)
- { }
+ { _class = FDClass::fd_pipe; }
std::shared_ptr<FDEntry>
clone() const override
@@ -196,12 +215,12 @@
DeviceFDEntry(EmulatedDriver *driver, std::string const& file_name,
bool close_on_exec = false)
: FDEntry(close_on_exec), _driver(driver), _fileName(file_name)
- { }
+ { _class = FDClass::fd_device; }
DeviceFDEntry(DeviceFDEntry const& dev, bool close_on_exec = false)
: FDEntry(close_on_exec), _driver(dev._driver),
_fileName(dev._fileName)
- { }
+ { _class = FDClass::fd_device; }
std::shared_ptr<FDEntry>
clone() const override
@@ -227,12 +246,12 @@
bool close_on_exec = false)
: HBFDEntry(0, sim_fd, close_on_exec),
_domain(domain), _type(type), _protocol(protocol)
- { }
+ { _class = FDClass::fd_socket; }
SocketFDEntry(SocketFDEntry const& reg, bool close_on_exec = false)
: HBFDEntry(reg._flags, reg._simFD, close_on_exec),
_domain(reg._domain), _type(reg._type), _protocol(reg._protocol)
- { }
+ { _class = FDClass::fd_socket; }
std::shared_ptr<FDEntry>
clone() const override
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 4902a13..a77bef3 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -356,12 +356,14 @@
{
memState->serialize(cp);
pTable->serialize(cp);
+ fds->serialize(cp);
+
/**
- * Checkpoints for file descriptors currently do not work. Need to
- * come back and fix them at a later date.
+ * Checkpoints for pipes, device drivers or sockets currently
+ * do not work. Need to come back and fix them at a later date.
*/
- warn("Checkpoints for file descriptors currently do not work.");
+ warn("Checkpoints for pipes, device drivers and sockets do not work.");
}
void
@@ -369,11 +371,12 @@
{
memState->unserialize(cp);
pTable->unserialize(cp);
+ fds->unserialize(cp);
/**
- * Checkpoints for file descriptors currently do not work. Need to
- * come back and fix them at a later date.
+ * Checkpoints for pipes, device drivers or sockets currently
+ * do not work. Need to come back and fix them at a later date.
*/
- warn("Checkpoints for file descriptors currently do not work.");
+ warn("Checkpoints for pipes, device drivers and sockets do not work.");
// The above returns a bool so that you could do something if you don't
// find the param in the checkpoint if you wanted to, like set a
default
// but in this case we'll just stick with the instantiated value if not
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 54e92b2..cd2d8d1 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -887,6 +887,8 @@
* process to act as a handle for the opened file.
*/
auto ffdp = std::make_shared<FileFDEntry>(sim_fd, host_flags, path, 0);
+ // Record the file mode for checkpoint restoring
+ ffdp->setFileMode(mode);
int tgt_fd = p->fds->allocFD(ffdp);
DPRINTF_SYSCALL(Verbose, "%s: sim_fd[%d], target_fd[%d] -> path:%s\n"
"(inferred from:%s)\n", desc->name(),
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/46619
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I4d0c7cd614a8abaffcae9aba1a28c9fdbc023c5a
Gerrit-Change-Number: 46619
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Rollet <tom.rol...@huawei.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s