43#include "params/Process.hh"
50 std::string
const& errout)
51 : _fdArray(), _input(input), _output(
output), _errout(errout),
53 {
"cin", STDIN_FILENO},
54 {
"stdin", STDIN_FILENO}},
56 {
"cout", STDOUT_FILENO},
57 {
"stdout", STDOUT_FILENO},
58 {
"cerr", STDERR_FILENO},
59 {
"stderr", STDERR_FILENO}}
62 std::map<std::string, int>::iterator it;
68 if ((it = _imap.find(input)) != _imap.end())
71 sim_fd = openInputFile(input);
73 auto ffd = std::make_shared<FileFDEntry>(sim_fd, O_RDONLY, input,
false);
74 _fdArray[STDIN_FILENO] = ffd;
80 if ((it = _oemap.find(output)) != _oemap.end())
83 sim_fd = openOutputFile(output);
85 ffd = std::make_shared<FileFDEntry>(sim_fd, O_WRONLY | O_CREAT | O_TRUNC,
87 _fdArray[STDOUT_FILENO] = ffd;
91 else if ((it = _oemap.find(errout)) != _oemap.end())
94 sim_fd = openOutputFile(errout);
96 ffd = std::make_shared<FileFDEntry>(sim_fd, O_WRONLY | O_CREAT | O_TRUNC,
98 _fdArray[STDERR_FILENO] = ffd;
102FDArray::updateFileOffsets()
104 for (
auto& fdp : _fdArray) {
110 auto ffd = std::dynamic_pointer_cast<FileFDEntry>(fdp);
119 int sim_fd = ffd->getSimFD();
120 ffd->setFileOffset(lseek(sim_fd, 0, SEEK_CUR));
125FDArray::restoreFileOffsets()
134 auto seek = [] (std::shared_ptr<FileFDEntry> ffd)
136 if (lseek(ffd->getSimFD(), ffd->getFileOffset(), SEEK_SET) < 0)
137 fatal(
"Unable to seek to location in %s", ffd->getFileName());
140 std::map<std::string, int>::iterator it;
149 std::shared_ptr<FDEntry> stdin_fde = _fdArray[STDIN_FILENO];
150 auto stdin_ffd = std::dynamic_pointer_cast<FileFDEntry>(stdin_fde);
152 if (_input != stdin_ffd->getFileName()) {
153 warn(
"Using new input file (%s) rather than checkpointed (%s)\n",
154 _input, stdin_ffd->getFileName());
155 stdin_ffd->setFileName(_input);
156 stdin_ffd->setFileOffset(0);
159 if ((it = _imap.find(stdin_ffd->getFileName())) != _imap.end()) {
160 stdin_ffd->setSimFD(it->second);
162 stdin_ffd->setSimFD(openInputFile(stdin_ffd->getFileName()));
173 std::shared_ptr<FDEntry> stdout_fde = _fdArray[STDOUT_FILENO];
174 auto stdout_ffd = std::dynamic_pointer_cast<FileFDEntry>(stdout_fde);
176 if (_output != stdout_ffd->getFileName()) {
177 warn(
"Using new output file (%s) rather than checkpointed (%s)\n",
178 _output, stdout_ffd->getFileName());
179 stdout_ffd->setFileName(_output);
180 stdout_ffd->setFileOffset(0);
183 if ((it = _oemap.find(stdout_ffd->getFileName())) != _oemap.end()) {
184 stdout_ffd->setSimFD(it->second);
186 stdout_ffd->setSimFD(openOutputFile(stdout_ffd->getFileName()));
197 std::shared_ptr<FDEntry> stderr_fde = _fdArray[STDERR_FILENO];
198 auto stderr_ffd = std::dynamic_pointer_cast<FileFDEntry>(stderr_fde);
200 if (_errout != stderr_ffd->getFileName()) {
201 warn(
"Using new error file (%s) rather than checkpointed (%s)\n",
202 _errout, stderr_ffd->getFileName());
203 stderr_ffd->setFileName(_errout);
204 stderr_ffd->setFileOffset(0);
207 if (stdout_ffd->getFileName() == stderr_ffd->getFileName()) {
209 stderr_ffd->setSimFD(stdout_ffd->getSimFD());
210 }
else if ((it = _oemap.find(stderr_ffd->getFileName())) != _oemap.end()) {
211 stderr_ffd->setSimFD(it->second);
213 stderr_ffd->setSimFD(openOutputFile(stderr_ffd->getFileName()));
217 for (
int tgt_fd = 3; tgt_fd < _fdArray.size(); tgt_fd++) {
218 std::shared_ptr<FDEntry> fdp = _fdArray[tgt_fd];
223 if (
auto pfd = std::dynamic_pointer_cast<PipeFDEntry>(fdp)) {
229 if (pfd->getEndType() == PipeFDEntry::EndType::write)
234 if (pipe(fd_pair) < 0)
235 fatal(
"Unable to create new pipe");
241 pfd->setSimFD(fd_pair[0]);
247 int prs = pfd->getPipeReadSource();
248 std::shared_ptr<FDEntry> write_fdp = _fdArray[prs];
251 auto write_pfd = std::dynamic_pointer_cast<PipeFDEntry>(write_fdp);
254 write_pfd->setSimFD(fd_pair[1]);
258 if (
auto dfd = std::dynamic_pointer_cast<DeviceFDEntry>(fdp)) {
264 fatal(
"Unable to restore checkpoints with emulated drivers");
268 if (
auto ffd = std::dynamic_pointer_cast<FileFDEntry>(fdp)) {
276 int sim_fd = openFile(ffd->getFileName(), ffd->getFlags(), 0664);
277 ffd->setSimFD(sim_fd);
284FDArray::allocFD(std::shared_ptr<FDEntry> in)
286 for (
int i = 0;
i < _fdArray.size();
i++) {
287 std::shared_ptr<FDEntry> fdp = _fdArray[
i];
293 fatal(
"Out of target file descriptors");
297FDArray::openFile(std::string
const& filename,
int flags, mode_t mode)
const
299 int sim_fd = open(filename.c_str(),
flags,
mode);
302 fatal(
"Unable to open %s with mode %d", filename,
mode);
306FDArray::openInputFile(std::string
const& filename)
const
308 return openFile(filename, O_RDONLY, 00);
312FDArray::openOutputFile(std::string
const& filename)
const
315 O_WRONLY | O_CREAT | O_TRUNC, 0664);
318std::shared_ptr<FDEntry>
319FDArray::getFDEntry(
int tgt_fd)
321 assert(0 <= tgt_fd && tgt_fd < _fdArray.size());
322 return _fdArray[tgt_fd];
326FDArray::setFDEntry(
int tgt_fd, std::shared_ptr<FDEntry> fdep)
328 assert(0 <= tgt_fd && tgt_fd < _fdArray.size());
329 _fdArray[tgt_fd] = fdep;
333FDArray::closeFDEntry(
int tgt_fd)
335 if (tgt_fd >= _fdArray.size() || tgt_fd < 0)
339 auto hbfdp = std::dynamic_pointer_cast<HBFDEntry>(_fdArray[tgt_fd]);
341 sim_fd = hbfdp->getSimFD();
348 _fdArray[tgt_fd] =
nullptr;
356 paramOut(cp,
"size", _fdArray.size());
357 for (
int tgt_fd = 0; tgt_fd < _fdArray.size(); tgt_fd++) {
358 auto fd = _fdArray[tgt_fd];
361 paramOut(cp,
"class", FDEntry::FDClass::fd_null);
374 assert(_fdArray.size() == size &&
375 "FDArray sizes do not match at unserialize!");
377 for (
int tgt_fd = 0; tgt_fd < _fdArray.size(); tgt_fd++) {
378 if (tgt_fd == STDIN_FILENO || tgt_fd == STDOUT_FILENO ||
379 tgt_fd == STDERR_FILENO)
383 paramIn(cp,
"class", fd_class);
384 std::shared_ptr<FDEntry> fdep;
387 case FDEntry::FDClass::fd_base:
388 panic(
"Abstract fd entry was serialized");
390 case FDEntry::FDClass::fd_hb:
391 fdep = std::make_shared<HBFDEntry>(0, 0);
393 case FDEntry::FDClass::fd_file:
394 fdep = std::make_shared<FileFDEntry>(0, 0,
"", 0, 00);
396 case FDEntry::FDClass::fd_device:
397 fdep = std::make_shared<DeviceFDEntry>(
nullptr,
"");
399 case FDEntry::FDClass::fd_pipe:
400 fdep = std::make_shared<PipeFDEntry>(
401 0, 0, PipeFDEntry::EndType::read);
403 case FDEntry::FDClass::fd_socket:
404 fdep = std::make_shared<SocketFDEntry>(0, 0, 0, 0);
406 case FDEntry::FDClass::fd_null:
409 panic(
"Unrecognized fd class");
413 fdep->unserialize(cp);
415 auto this_ffd = std::dynamic_pointer_cast<FileFDEntry>(fdep);
418 setFDEntry(tgt_fd, fdep);
420 mode_t
mode = this_ffd->getFileMode();
421 std::string
const& path = this_ffd->getFileName();
422 int flags = this_ffd->getFlags();
425 int sim_fd = openFile(path,
flags,
mode);
426 this_ffd->setSimFD(sim_fd);
429 uint64_t file_offset = this_ffd->getFileOffset();
430 lseek(sim_fd, file_offset, SEEK_SET);
FDArray(std::string const &input, std::string const &output, std::string const &errout)
Initialize the file descriptor array and set the standard file descriptors to defaults or values pass...
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::ostream CheckpointOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
static void output(const char *filename)
std::string csprintf(const char *format, const Args &...args)