dev: Add post-fork handling for disk images
authorAndreas Sandberg <andreas@sandberg.pp.se>
Thu, 26 Nov 2015 10:11:52 +0000 (10:11 +0000)
committerAndreas Sandberg <andreas@sandberg.pp.se>
Thu, 26 Nov 2015 10:11:52 +0000 (10:11 +0000)
This changeset adds support for notifying the disk images that the simulator has
been forked. We need to disable the saving of the CoW disk image from the child
process, and we need to make sure that systems which use a raw disk image are
not allowed to fork to avoid two or more gem5 processes writing to the same disk
image.

Signed-off-by: Andreas Sandberg <andreas@sandberg.pp.se>
[sascha.bischoff@arm.com: Rebased patches onto a newer gem5 version]
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
src/dev/storage/disk_image.cc
src/dev/storage/disk_image.hh

index 24688f55aad7a79b2d0da0be0fe37949e626df44..e7fda40a29503489735ae1eab2539e889acfceca 100644 (file)
@@ -64,6 +64,17 @@ RawDiskImage::RawDiskImage(const Params* p)
 RawDiskImage::~RawDiskImage()
 { close(); }
 
+void
+RawDiskImage::notifyFork()
+{
+    if (initialized && !readonly)
+        panic("Attempting to fork system with read-write raw disk image.");
+
+    const Params *p(dynamic_cast<const Params *>(params()));
+    close();
+    open(p->image_file, p->read_only);
+}
+
 void
 RawDiskImage::open(const string &filename, bool rd_only)
 {
@@ -197,6 +208,16 @@ CowDiskImage::~CowDiskImage()
     }
 }
 
+void
+CowDiskImage::notifyFork()
+{
+    if (!dynamic_cast<const Params *>(params())->read_only &&
+        !filename.empty()) {
+        inform("Disabling saving of COW image in forked child process.\n");
+        filename = "";
+    }
+}
+
 void
 SafeRead(ifstream &stream, void *data, int count)
 {
@@ -311,8 +332,12 @@ SafeWriteSwap(ofstream &stream, const T &data)
 void
 CowDiskImage::save() const
 {
-    save(filename);
-}
+    // filename will be set to the empty string to disable saving of
+    // the COW image in a forked child process. Save will still be
+    // called because there is no easy way to unregister the exit
+    // callback.
+    if (!filename.empty())
+        save(filename);}
 
 void
 CowDiskImage::save(const string &file) const
index 43e6adf5e938a467401ea8a274d1ad12859b7811..2a59dc0c35d284091457f6f7276c9cba528066e3 100644 (file)
@@ -82,6 +82,8 @@ class RawDiskImage : public DiskImage
     RawDiskImage(const Params *p);
     ~RawDiskImage();
 
+    void notifyFork() override;
+
     void close();
     void open(const std::string &filename, bool rd_only = false);
 
@@ -123,6 +125,8 @@ class CowDiskImage : public DiskImage
     CowDiskImage(const Params *p);
     ~CowDiskImage();
 
+    void notifyFork() override;
+
     void initSectorTable(int hash_size);
     bool open(const std::string &file);
     void save() const;