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

Reply via email to