Skip to content

Commit 84ddf4f

Browse files
committed
Moved responsibility of de/ser into FdTable and FileMonitor
Deserializing and serializing an FdTable is now performed by the class itself instead of in a free function FileMonitor has a public member function that is used for serialization. Each derived type that requires special/additional logic, extends the virtual member function serialize_type.
1 parent cce8b4c commit 84ddf4f

25 files changed

Lines changed: 177 additions & 76 deletions

src/BpfMapMonitor.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@ class BpfMapMonitor : public FileMonitor {
1414
public:
1515
BpfMapMonitor(uint64_t key_size, uint64_t value_size) : key_size_(key_size), value_size_(value_size) {}
1616

17-
virtual Type type() override { return BpfMap; }
17+
virtual Type type() const override { return BpfMap; }
1818

1919
uint64_t key_size() const { return key_size_; }
2020
uint64_t value_size() const { return value_size_; }
2121

2222
private:
23+
virtual void serialize_type(pcp::FileMonitor::Builder& builder) const noexcept override {
24+
auto bpf = builder.initBpf();
25+
bpf.setKeySize(key_size_);
26+
bpf.setValueSize(value_size_);
27+
}
28+
2329
uint64_t key_size_;
2430
uint64_t value_size_;
2531
};

src/FdTable.cc

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66

77
#include <unordered_set>
88

9+
#include "BpfMapMonitor.h"
10+
#include "FileMonitor.h"
11+
#include "MagicSaveDataMonitor.h"
12+
#include "MmappedFileMonitor.h"
13+
#include "NonvirtualPerfCounterMonitor.h"
14+
#include "ODirectFileMonitor.h"
15+
#include "PreserveFileMonitor.h"
16+
#include "ProcFdDirMonitor.h"
17+
#include "ProcMemMonitor.h"
18+
#include "ProcStatMonitor.h"
19+
#include "RRPageMonitor.h"
20+
#include "StdioMonitor.h"
21+
#include "SysCpuMonitor.h"
922
#include "rr/rr.h"
1023

1124
#include "AddressSpace.h"
@@ -253,4 +266,86 @@ vector<int> FdTable::fds_to_close_after_exec(RecordTask* t) {
253266
return fds_to_close;
254267
}
255268

269+
void FdTable::deserialize(Task* leader,
270+
const pcp::ProcessSpace::Reader& leader_reader) {
271+
auto monitors = leader_reader.getMonitors();
272+
for (auto m : monitors) {
273+
FileMonitor::Type t = (FileMonitor::Type)m.getType();
274+
auto fd = m.getFd();
275+
if (!is_monitoring(m.getFd())) {
276+
switch (t) {
277+
case FileMonitor::Base:
278+
FATAL() << "Can't add abstract type";
279+
break;
280+
case FileMonitor::MagicSaveData:
281+
add_monitor(leader, fd, new MagicSaveDataMonitor());
282+
break;
283+
case FileMonitor::Mmapped: {
284+
const auto mmap = m.getMmap();
285+
add_monitor(leader, fd,
286+
new MmappedFileMonitor(mmap.getDead(), mmap.getDevice(),
287+
mmap.getInode()));
288+
} break;
289+
case FileMonitor::Preserve:
290+
add_monitor(leader, fd, new PreserveFileMonitor());
291+
break;
292+
case FileMonitor::ProcFd: {
293+
const auto p_fd = m.getProcFd();
294+
const auto tuid = TaskUid(p_fd.getTid(), p_fd.getSerial());
295+
add_monitor(leader, fd, new ProcFdDirMonitor(tuid));
296+
break;
297+
}
298+
case FileMonitor::ProcMem: {
299+
const auto pmem = m.getProcMem();
300+
add_monitor(leader, fd,
301+
new ProcMemMonitor(AddressSpaceUid(pmem.getTid(),
302+
pmem.getSerial(),
303+
pmem.getExecCount())));
304+
} break;
305+
case FileMonitor::Stdio:
306+
add_monitor(leader, fd, new StdioMonitor(m.getStdio()));
307+
break;
308+
case FileMonitor::VirtualPerfCounter:
309+
FATAL() << "VirtualPerCounter Monitor deserializing unimplemented!\n";
310+
break;
311+
case FileMonitor::NonvirtualPerfCounter:
312+
add_monitor(leader, fd, new NonvirtualPerfCounterMonitor());
313+
break;
314+
case FileMonitor::SysCpu:
315+
add_monitor(leader, fd, new SysCpuMonitor(leader, ""));
316+
break;
317+
case FileMonitor::ProcStat:
318+
add_monitor(
319+
leader, fd,
320+
new ProcStatMonitor(leader, data_to_str(m.getProcStat())));
321+
break;
322+
case FileMonitor::RRPage:
323+
add_monitor(leader, fd, new RRPageMonitor());
324+
break;
325+
case FileMonitor::ODirect:
326+
add_monitor(leader, fd, new ODirectFileMonitor());
327+
break;
328+
case FileMonitor::BpfMap:
329+
add_monitor(leader, fd,
330+
new BpfMapMonitor(m.getBpf().getKeySize(),
331+
m.getBpf().getValueSize()));
332+
break;
333+
default:
334+
FATAL() << "unhandled FileMonitor: " << file_monitor_type_name(t);
335+
}
336+
}
337+
}
338+
}
339+
340+
void FdTable::serialize(pcp::ProcessSpace::Builder& leader_builder) const {
341+
auto serialized_fd_mons = leader_builder.initMonitors(fds.size());
342+
auto mon_index = 0;
343+
for (const auto& mon : fds) {
344+
const auto fd = mon.first;
345+
const auto& monitor = mon.second;
346+
auto builder = serialized_fd_mons[mon_index++];
347+
monitor->serialize(fd, builder);
348+
}
349+
}
350+
256351
} // namespace rr

src/FdTable.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "FileMonitor.h"
1111
#include "HasTaskSet.h"
12+
#include "rr_pcp.capnp.h"
1213

1314
namespace rr {
1415

@@ -69,7 +70,11 @@ class FdTable : public HasTaskSet {
6970
* Close fds in list after an exec.
7071
*/
7172
void close_after_exec(ReplayTask* t, const std::vector<int>& fds_to_close);
72-
const std::unordered_map<int, FileMonitor::shr_ptr>& monitored_fds() const { return fds; }
73+
74+
void serialize(pcp::ProcessSpace::Builder& leader_builder) const;
75+
76+
void deserialize(Task* leader, const pcp::ProcessSpace::Reader& leader_reader);
77+
7378
private:
7479
FdTable() : fd_count_beyond_limit(0) {}
7580
FdTable(const FdTable& other) : fds(other.fds),

src/FileMonitor.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,10 @@ std::string file_monitor_type_name(FileMonitor::Type t) {
113113
}
114114
}
115115

116+
void FileMonitor::serialize(int fd, pcp::FileMonitor::Builder& builder) const noexcept {
117+
builder.setFd(fd);
118+
builder.setType(type());
119+
serialize_type(builder);
120+
}
121+
116122
}

src/FileMonitor.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Task;
1313

1414
#include "preload/preload_interface.h"
1515
#include "util.h"
16+
#include "rr_pcp.capnp.h"
1617

1718
namespace rr {
1819

@@ -42,7 +43,7 @@ class FileMonitor {
4243
BpfMap,
4344
};
4445

45-
virtual Type type() { return Base; }
46+
virtual Type type() const { return Base; }
4647

4748
/**
4849
* Overriding this to return true will cause close() (and related fd-smashing
@@ -128,6 +129,13 @@ class FileMonitor {
128129
virtual enum syscallbuf_fd_classes get_syscallbuf_class() {
129130
return FD_CLASS_TRACED;
130131
}
132+
133+
/** Serialize this file monitor for persistent checkpoints. */
134+
void serialize(int fd, pcp::FileMonitor::Builder& builder) const noexcept;
135+
136+
private:
137+
// default serialize_type does nothing
138+
virtual void serialize_type(pcp::FileMonitor::Builder&) const noexcept {}
131139
};
132140

133141
std::string file_monitor_type_name(FileMonitor::Type t);

src/MagicSaveDataMonitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class MagicSaveDataMonitor : public FileMonitor {
1414
public:
1515
MagicSaveDataMonitor() {}
1616

17-
virtual Type type() override { return MagicSaveData; }
17+
virtual Type type() const override { return MagicSaveData; }
1818

1919
virtual void did_write(Task* t, const std::vector<Range>& ranges,
2020
LazyOffset& offset) override;

src/MmappedFileMonitor.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,11 @@ void MmappedFileMonitor::did_write(Task* t, const std::vector<Range>& ranges,
110110
}
111111
}
112112

113+
void MmappedFileMonitor::serialize_type(pcp::FileMonitor::Builder& builder) const noexcept {
114+
auto mmap = builder.initMmap();
115+
mmap.setDead(dead_);
116+
mmap.setDevice(device_);
117+
mmap.setInode(inode_);
118+
}
119+
113120
} // namespace rr

src/MmappedFileMonitor.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class MmappedFileMonitor : public FileMonitor {
2020
MmappedFileMonitor(Task* t, EmuFile::shr_ptr f);
2121
MmappedFileMonitor(bool dead, dev_t device, ino_t inode) noexcept;
2222

23-
virtual Type type() override { return Mmapped; }
23+
virtual Type type() const override { return Mmapped; }
2424
void revive() { dead_ = false; }
2525
// If this write could potentially affect memory we need to PREVENT_SWITCH,
2626
// since the timing of the write is otherwise unpredictable from our
@@ -34,8 +34,9 @@ class MmappedFileMonitor : public FileMonitor {
3434
*/
3535
virtual void did_write(Task* t, const std::vector<Range>& ranges,
3636
LazyOffset& offset) override;
37-
std::tuple<bool, dev_t, ino_t> info() const { return std::tuple<bool, dev_t, ino_t>{dead_, device_, inode_}; }
37+
3838
private:
39+
void serialize_type(pcp::FileMonitor::Builder& builder) const noexcept override;
3940
// Whether this monitor is still actively monitoring
4041
bool dead_;
4142
dev_t device_;

src/NonvirtualPerfCounterMonitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class NonvirtualPerfCounterMonitor : public FileMonitor {
1515
public:
1616
NonvirtualPerfCounterMonitor() {}
1717

18-
virtual Type type() override { return NonvirtualPerfCounter; }
18+
virtual Type type() const override { return NonvirtualPerfCounter; }
19+
1920
};
2021

2122
} // namespace rr

src/ODirectFileMonitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ODirectFileMonitor : public FileMonitor {
1717
public:
1818
ODirectFileMonitor() : FileMonitor() {};
1919

20-
virtual Type type() override { return ODirect; }
20+
virtual Type type() const override { return ODirect; }
2121
};
2222

2323
} // namespace rr

0 commit comments

Comments
 (0)