gem5  v20.1.0.0
fs9p.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include "dev/virtio/fs9p.hh"
39 
40 #include <fcntl.h>
41 #include <netdb.h>
42 #include <netinet/in.h>
43 #include <sys/socket.h>
44 #include <sys/types.h>
45 #include <sys/un.h>
46 #include <sys/wait.h>
47 #include <unistd.h>
48 
49 #include <csignal>
50 #include <fstream>
51 
52 #include "base/callback.hh"
53 #include "base/output.hh"
54 #include "debug/VIO9P.hh"
55 #include "debug/VIO9PData.hh"
56 #include "params/VirtIO9PBase.hh"
57 #include "params/VirtIO9PDiod.hh"
58 #include "params/VirtIO9PProxy.hh"
59 #include "params/VirtIO9PSocket.hh"
60 #include "sim/system.hh"
61 
62 struct P9MsgInfo {
63  P9MsgInfo(P9MsgType _type, std::string _name)
64  : type(_type), name(_name) {}
65 
67  std::string name;
68 };
69 
70 typedef std::map<P9MsgType, P9MsgInfo> P9MsgInfoMap;
71 
72 #define P9MSG(type, name) \
73  { (type), P9MsgInfo((type), "T" # name ) }, \
74  { (type + 1), P9MsgInfo((type + 1), "R" # name ) }
75 
76 static const P9MsgInfoMap p9_msg_info {
77  P9MSG(6, LERROR),
78  P9MSG(8, STATFS),
79  P9MSG(12, LOPEN),
80  P9MSG(14, LCREATE),
81  P9MSG(16, SYMLINK),
82  P9MSG(18, MKNOD),
83  P9MSG(20, RENAME),
84  P9MSG(22, READLINK),
85  P9MSG(24, GETATTR),
86  P9MSG(26, SETATTR),
87  P9MSG(30, XATTRWALK),
88  P9MSG(32, XATTRCREATE),
89  P9MSG(40, READDIR),
90  P9MSG(50, FSYNC),
91  P9MSG(52, LOCK),
92  P9MSG(54, GETLOCK),
93  P9MSG(70, LINK),
94  P9MSG(72, MKDIR),
95  P9MSG(74, RENAMEAT),
96  P9MSG(76, UNLINKAT),
97  P9MSG(100, VERSION),
98  P9MSG(102, AUTH),
99  P9MSG(104, ATTACH),
100  P9MSG(106, ERROR),
101  P9MSG(108, FLUSH),
102  P9MSG(110, WALK),
103  P9MSG(112, OPEN),
104  P9MSG(114, CREATE),
105  P9MSG(116, READ),
106  P9MSG(118, WRITE),
107  P9MSG(120, CLUNK),
108  P9MSG(122, REMOVE),
109  P9MSG(124, STAT),
110  P9MSG(126, WSTAT),
111 };
112 
113 #undef P9MSG
114 
116  : VirtIODeviceBase(params, ID_9P,
117  sizeof(Config) + params->tag.size(),
118  F_MOUNT_TAG),
119  queue(params->system->physProxy, byteOrder, params->queueSize, *this)
120 {
121  config.reset((Config *)
122  operator new(configSize));
123  config->len = htog(params->tag.size(), byteOrder);
124  memcpy(config->tag, params->tag.c_str(), params->tag.size());
125 
127 }
128 
129 
131 {
132 }
133 
134 void
136 {
137  readConfigBlob(pkt, cfgOffset, (uint8_t *)config.get());
138 }
139 
140 void
142 {
143  DPRINTF(VIO9P, "Got input data descriptor (len: %i)\n", desc->size());
144  DPRINTF(VIO9P, "\tPending transactions: %i\n", parent.pendingTransactions.size());
145 
147  desc->chainRead(0, (uint8_t *)&header, sizeof(header));
148  header = p9toh(header);
149 
150  uint8_t data[header.len - sizeof(header)];
151  desc->chainRead(sizeof(header), data, sizeof(data));
152 
153  // Keep track of pending transactions
154  parent.pendingTransactions[header.tag] = desc;
155 
156  DPRINTF(VIO9P, "recvTMsg\n");
157  parent.dumpMsg(header, data, sizeof(data));
158 
159  // Notify device of message
160  parent.recvTMsg(header, data, sizeof(data));
161 }
162 
163 void
164 VirtIO9PBase::sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
165 {
166  DPRINTF(VIO9P, "Sending RMsg\n");
167  dumpMsg(header, data, size);
168  DPRINTF(VIO9P, "\tPending transactions: %i\n", pendingTransactions.size());
169  assert(header.len >= sizeof(header));
170 
171  VirtDescriptor *main_desc(pendingTransactions[header.tag]);
172  pendingTransactions.erase(header.tag);
173 
174  // Find the first output descriptor
175  VirtDescriptor *out_desc(main_desc);
176  while (out_desc && !out_desc->isOutgoing())
177  out_desc = out_desc->next();
178  if (!out_desc)
179  panic("sendRMsg: Framing error, no output descriptor.\n");
180 
181  P9MsgHeader header_out(htop9(header));
182  header_out.len = htop9(sizeof(P9MsgHeader) + size);
183 
184  out_desc->chainWrite(0, (uint8_t *)&header_out, sizeof(header_out));
185  out_desc->chainWrite(sizeof(header_out), data, size);
186 
187  queue.produceDescriptor(main_desc, sizeof(P9MsgHeader) + size);
188  kick();
189 }
190 
191 void
192 VirtIO9PBase::dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
193 {
194 #ifndef NDEBUG
195  if (!DTRACE(VIO9P))
196  return;
197 
198  const P9MsgInfoMap::const_iterator it_msg(p9_msg_info.find(header.type));
199  if (it_msg != p9_msg_info.cend()) {
200  const P9MsgInfo &info(it_msg->second);
201  DPRINTF(VIO9P, "P9Msg[len = %i, type = %s (%i), tag = %i]\n",
202  header.len, info.name, header.type, header.tag);
203  } else {
204  DPRINTF(VIO9P, "P9Msg[len = %i, type = Unknown (%i), tag = %i]\n",
205  header.len, header.type, header.tag);
206  }
207  DDUMP(VIO9PData, data, size);
208 #endif
209 }
210 
211 
213  : VirtIO9PBase(params), deviceUsed(false)
214 {
215 }
216 
218 {
219 }
220 
221 
222 void
224 {
225  if (deviceUsed) {
226  warn("Serializing VirtIO9Base device after device has been used. It is "
227  "likely that state will be lost, and that the device will cease "
228  "to work!");
229  }
231 
233 }
234 
235 void
237 {
239 
240  if (deviceUsed) {
241  warn("Unserializing VirtIO9Base device after device has been used. It is "
242  "likely that state has been lost, and that the device will cease "
243  "to work!");
244  }
246 }
247 
248 
249 void
251  const uint8_t *data, size_t size)
252 {
253  deviceUsed = true;
254  assert(header.len == sizeof(header) + size);
255  // While technically not needed, we send the packet as one
256  // contiguous segment to make some packet dissectors happy.
257  uint8_t out[header.len];
258  P9MsgHeader header_out(htop9(header));
259  memcpy(out, (uint8_t *)&header_out, sizeof(header_out));
260  memcpy(out + sizeof(header_out), data, size);
261  writeAll(out, sizeof(header_out) + size);
262 }
263 
264 void
266 {
268  readAll((uint8_t *)&header, sizeof(header));
269  header = p9toh(header);
270 
271  const ssize_t payload_len(header.len - sizeof(header));
272  if (payload_len < 0)
273  panic("Payload length is negative!\n");
274  uint8_t data[payload_len];
275  readAll(data, payload_len);
276 
277  sendRMsg(header, data, payload_len);
278 }
279 
280 
281 void
282 VirtIO9PProxy::readAll(uint8_t *data, size_t len)
283 {
284  while (len) {
285  ssize_t ret;
286  while ((ret = read(data, len)) == -EAGAIN)
287  ;
288  if (ret < 0)
289  panic("readAll: Read failed: %i\n", -ret);
290 
291  len -= ret;
292  data += ret;
293  }
294 }
295 
296 void
297 VirtIO9PProxy::writeAll(const uint8_t *data, size_t len)
298 {
299  while (len) {
300  ssize_t ret;
301  while ((ret = write(data, len)) == -EAGAIN)
302  ;
303  if (ret < 0)
304  panic("writeAll: write failed: %i\n", -ret);
305 
306  len -= ret;
307  data += ret;
308  }
309 }
310 
311 
312 
314  : VirtIO9PProxy(params),
315  fd_to_diod(-1), fd_from_diod(-1), diod_pid(-1)
316 {
317  // Register an exit callback so we can kill the diod process
318  registerExitCallback([this]() { terminateDiod(); });
319 }
320 
322 {
323 }
324 
325 void
327 {
328  startDiod();
329  dataEvent.reset(new DiodDataEvent(*this, fd_from_diod, POLLIN));
331 }
332 
333 void
335 {
336  const Params *p(dynamic_cast<const Params *>(params()));
337  int pipe_rfd[2];
338  int pipe_wfd[2];
339  const int DIOD_RFD = 3;
340  const int DIOD_WFD = 4;
341 
342  const char *diod(p->diod.c_str());
343 
344  DPRINTF(VIO9P, "Using diod at %s \n", p->diod.c_str());
345 
346  if (pipe(pipe_rfd) == -1 || pipe(pipe_wfd) == -1)
347  panic("Failed to create DIOD pipes: %i\n", errno);
348 
349  fd_to_diod = pipe_rfd[1];
350  fd_from_diod = pipe_wfd[0];
351 
352  // Create Unix domain socket
353  int socket_id = socket(AF_UNIX, SOCK_STREAM, 0);
354  if (socket_id == -1) {
355  panic("Socket creation failed %i \n", errno);
356  }
357  // Bind the socket to a path which will not be read
358  struct sockaddr_un socket_address;
359  memset(&socket_address, 0, sizeof(struct sockaddr_un));
360  socket_address.sun_family = AF_UNIX;
361 
362  const std::string socket_path = simout.resolve(p->socketPath);
363  fatal_if(!OutputDirectory::isAbsolute(socket_path), "Please make the" \
364  " output directory an absolute path, else diod will fail!\n");
365 
366  // Prevent overflow in strcpy
367  fatal_if(sizeof(socket_address.sun_path) <= socket_path.length(),
368  "Incorrect length of socket path");
369  strncpy(socket_address.sun_path, socket_path.c_str(),
370  sizeof(socket_address.sun_path) - 1);
371  if (bind(socket_id, (struct sockaddr*) &socket_address,
372  sizeof(struct sockaddr_un)) == -1){
373  perror("Socket binding");
374  panic("Socket binding to %i failed - most likely the output dir" \
375  " and hence unused socket already exists \n", socket_id);
376  }
377 
378  diod_pid = fork();
379  if (diod_pid == -1) {
380  panic("Fork failed: %i\n", errno);
381  } else if (diod_pid == 0) {
382  // Create the socket which will later by used by the diod process
383  close(STDIN_FILENO);
384  if (dup2(pipe_rfd[0], DIOD_RFD) == -1 ||
385  dup2(pipe_wfd[1], DIOD_WFD) == -1) {
386 
387  panic("Failed to setup read/write pipes: %i\n",
388  errno);
389  }
390 
391  // Start diod
392  execlp(diod, diod,
393  "-d", DTRACE(VIO9P) ? "1" : "0", // show debug output
394  "-f", // start in foreground
395  "-r", "3", // setup read FD
396  "-w", "4", // setup write FD
397  "-e", p->root.c_str(), // path to export
398  "-n", // disable security
399  "-S", // squash all users
400  "-l", socket_path.c_str(), // pass the socket
401  (char *)NULL);
402  perror("Starting DIOD");
403  panic("Failed to execute diod to %s: %i\n",socket_path, errno);
404  } else {
405  close(pipe_rfd[0]);
406  close(pipe_wfd[1]);
407  inform("Started diod with PID %u, you might need to manually kill " \
408  " diod if gem5 crashes \n", diod_pid);
409  }
410 
411 #undef DIOD_RFD
412 #undef DIOD_WFD
413 }
414 
415 ssize_t
416 VirtIO9PDiod::read(uint8_t *data, size_t len)
417 {
418  assert(fd_from_diod != -1);
419  const int ret(::read(fd_from_diod, (void *)data, len));
420  return ret < 0 ? -errno : ret;
421 }
422 
423 ssize_t
424 VirtIO9PDiod::write(const uint8_t *data, size_t len)
425 {
426  assert(fd_to_diod != -1);
427  const int ret(::write(fd_to_diod, (const void *)data, len));
428  return ret < 0 ? -errno : ret;
429 }
430 
431 void
433 {
435 }
436 
437 void
439 {
440  assert(diod_pid != -1);
441 
442  DPRINTF(VIO9P, "Trying to kill diod at pid %u \n", diod_pid);
443 
444  if (kill(diod_pid, SIGTERM) != 0) {
445  perror("Killing diod process");
446  warn("Failed to kill diod using SIGTERM");
447  return;
448  }
449 
450  // Check if kill worked
451  for (unsigned i = 0; i < 5; i++) {
452  int wait_return = waitpid(diod_pid, NULL, WNOHANG);
453  if (wait_return == diod_pid) {
454  // Managed to kill diod
455  return;
456  } else if (wait_return == 0) {
457  // Diod is not killed so sleep and try again
458  usleep(500);
459  } else {
460  // Failed in waitpid
461  perror("Waitpid");
462  warn("Failed in waitpid");
463  }
464  }
465 
466  // Try again to kill diod with sigkill
467  inform("Trying to kill diod with SIGKILL as SIGTERM failed \n");
468  if (kill(diod_pid, SIGKILL) != 0) {
469  perror("Killing diod process");
470  warn("Failed to kill diod using SIGKILL");
471  } else {
472  // Managed to kill diod
473  return;
474  }
475 
476 }
477 VirtIO9PDiod *
478 VirtIO9PDiodParams::create()
479 {
480  return new VirtIO9PDiod(this);
481 }
482 
483 
484 
485 
487  : VirtIO9PProxy(params), fdSocket(-1)
488 {
489 }
490 
492 {
493 }
494 
495 void
497 {
498  connectSocket();
499  dataEvent.reset(new SocketDataEvent(*this, fdSocket, POLLIN));
501 }
502 
503 void
505 {
506  const Params &p(dynamic_cast<const Params &>(*params()));
507 
508  int ret;
509  struct addrinfo hints, *result;
510  memset(&hints, 0, sizeof(hints));
511  hints.ai_family = AF_UNSPEC;
512  hints.ai_socktype = SOCK_STREAM;
513  hints.ai_flags = 0;
514  hints.ai_protocol = 0;
515 
516  if ((ret = getaddrinfo(p.server.c_str(), p.port.c_str(),
517  &hints, &result)) != 0)
518  panic("getaddrinfo: %s\n", gai_strerror(ret));
519 
520  DPRINTF(VIO9P, "Connecting to 9p server '%s'.\n", p.server);
521  for (struct addrinfo *rp = result; rp; rp = rp->ai_next) {
522  fdSocket = socket(rp->ai_family, rp->ai_socktype,
523  rp->ai_protocol);
524  if (fdSocket == -1) {
525  continue;
526  } else if (connect(fdSocket, rp->ai_addr, rp->ai_addrlen) != -1) {
527  break;
528  } else {
529  close(fdSocket);
530  fdSocket = -1;
531  }
532  }
533 
534  freeaddrinfo(result);
535 
536  if (fdSocket == -1)
537  panic("Failed to connect to 9p server (%s:%s)", p.server, p.port);
538 }
539 
540 void
542 {
543  panic("9P Socket disconnected!\n");
544 }
545 
546 ssize_t
547 VirtIO9PSocket::read(uint8_t *data, size_t len)
548 {
549  assert(fdSocket != -1);
550  int ret;
551 
552  ret = ::recv(fdSocket, (void *)data, len, 0);
553  if (ret == 0)
555 
556  return ret < 0 ? -errno : ret;
557 }
558 
559 ssize_t
560 VirtIO9PSocket::write(const uint8_t *data, size_t len)
561 {
562  assert(fdSocket != -1);
563  int ret(::send(fdSocket, (const void *)data, len, 0));
564  return ret < 0 ? -errno : ret;
565 }
566 
567 void
569 {
571 }
572 
573 
575 VirtIO9PSocketParams::create()
576 {
577  return new VirtIO9PSocket(this);
578 }
VirtIO9PProxy::write
virtual ssize_t write(const uint8_t *data, size_t len)=0
Write data to the server behind the proxy.
VirtIO9PBase::dumpMsg
void dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
Dump a 9p RPC message on the debug output.
Definition: fs9p.cc:192
VirtDescriptor::size
size_t size() const
Retrieve the size of this descriptor.
Definition: base.hh:202
VirtIO9PProxy::deviceUsed
bool deviceUsed
Bool to track if the device has been used or not.
Definition: fs9p.hh:281
VirtIO9PSocket::dataEvent
std::unique_ptr< SocketDataEvent > dataEvent
Definition: fs9p.hh:381
warn
#define warn(...)
Definition: logging.hh:239
VirtIO9PBase::VirtIO9PBase
VirtIO9PBase(Params *params)
Definition: fs9p.cc:115
VirtQueue::produceDescriptor
void produceDescriptor(VirtDescriptor *desc, uint32_t len)
Send a descriptor chain to the guest.
Definition: base.cc:290
system.hh
VirtIO9PProxy::recvTMsg
void recvTMsg(const P9MsgHeader &header, const uint8_t *data, size_t size) override
Handle incoming 9p RPC message.
Definition: fs9p.cc:250
data
const char data[]
Definition: circlebuf.test.cc:42
VirtIO9PBase::readConfig
void readConfig(PacketPtr pkt, Addr cfgOffset)
Read from the configuration space of a device.
Definition: fs9p.cc:135
fs9p.hh
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
ArmISA::byteOrder
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:449
VirtIO9PProxy::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: fs9p.cc:236
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
VirtIO9PSocket::read
ssize_t read(uint8_t *data, size_t len)
Read data from the server behind the proxy.
Definition: fs9p.cc:547
VirtIO9PProxy::serverDataReady
void serverDataReady()
Notification of pending data from server.
Definition: fs9p.cc:265
VirtIO9PSocket::SocketDataEvent::process
void process(int revent)
Definition: fs9p.cc:568
VirtIODeviceBase::registerQueue
void registerQueue(VirtQueue &queue)
Register a new VirtQueue with the device model.
Definition: base.cc:477
P9MsgInfo::type
P9MsgType type
Definition: fs9p.cc:66
VirtIODeviceBase
Base class for all VirtIO-based devices.
Definition: base.hh:558
VirtIO9PProxy::readAll
void readAll(uint8_t *data, size_t len)
Convenience function that reads exactly len bytes.
Definition: fs9p.cc:282
VirtIO9PBase::FSQueue::parent
VirtIO9PBase & parent
Definition: fs9p.hh:158
header
output header
Definition: nop.cc:36
VirtIO9PDiod::fd_to_diod
int fd_to_diod
fd for data pipe going to diod (write end)
Definition: fs9p.hh:326
DTRACE
#define DTRACE(x)
Definition: debug.hh:146
VirtIO9PDiod::VirtIO9PDiod
VirtIO9PDiod(Params *params)
Definition: fs9p.cc:313
P9MsgInfoMap
std::map< P9MsgType, P9MsgInfo > P9MsgInfoMap
Definition: fs9p.cc:70
PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:159
OutputDirectory::resolve
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
Definition: output.cc:203
output.hh
P9MSG
#define P9MSG(type, name)
Definition: fs9p.cc:72
VirtIO9PDiod
VirtIO 9p proxy that communicates with the diod 9p server using pipes.
Definition: fs9p.hh:290
VirtIO9PDiod::fd_from_diod
int fd_from_diod
fd for data pipe coming from diod (read end)
Definition: fs9p.hh:328
VirtIO9PDiod::DiodDataEvent::process
void process(int revent)
Definition: fs9p.cc:432
VirtIO9PBase::pendingTransactions
std::map< P9Tag, VirtDescriptor * > pendingTransactions
Map between 9p transaction tags and descriptors where they appeared.
Definition: fs9p.hh:200
OutputDirectory::isAbsolute
static bool isAbsolute(const std::string &name)
Test if a path is absolute.
Definition: output.hh:274
VirtIO9PSocket::VirtIO9PSocket
VirtIO9PSocket(Params *params)
Definition: fs9p.cc:486
htop9
T htop9(T v)
Convert host byte order to p9 byte order (LE)
Definition: fs9p.hh:68
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
VirtIO9PSocket::~VirtIO9PSocket
virtual ~VirtIO9PSocket()
Definition: fs9p.cc:491
VirtIO9PDiod::terminateDiod
void terminateDiod()
Kill the diod child process at the end of the simulation.
Definition: fs9p.cc:438
cp
Definition: cprintf.cc:40
VirtIO9PBase::~VirtIO9PBase
virtual ~VirtIO9PBase()
Definition: fs9p.cc:130
VirtIODeviceBase::configSize
const size_t configSize
Size of the device's configuration space.
Definition: base.hh:847
registerExitCallback
void registerExitCallback(const std::function< void()> &callback)
Register an exit callback.
Definition: core.cc:140
VirtIO9PProxy::VirtIO9PProxy
VirtIO9PProxy(Params *params)
Definition: fs9p.cc:212
VirtIO9PDiod::dataEvent
std::unique_ptr< DiodDataEvent > dataEvent
Definition: fs9p.hh:330
VirtIO9PProxy::read
virtual ssize_t read(uint8_t *data, size_t len)=0
Read data from the server behind the proxy.
VirtIO9PDiod::startDiod
void startDiod()
Start diod and setup the communication pipes.
Definition: fs9p.cc:334
VirtIO9PSocket::write
ssize_t write(const uint8_t *data, size_t len)
Write data to the server behind the proxy.
Definition: fs9p.cc:560
VirtIO9PDiod::DiodDataEvent
Definition: fs9p.hh:311
VirtIO9PSocket::startup
void startup()
startup() is the final initialization call before simulation.
Definition: fs9p.cc:496
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
VirtIODeviceBase::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: base.cc:351
htog
T htog(T value, ByteOrder guest_byte_order)
Definition: byteswap.hh:155
VirtIODeviceBase::readConfigBlob
void readConfigBlob(PacketPtr pkt, Addr cfgOffset, const uint8_t *cfg)
Read configuration data from a device structure.
Definition: base.cc:420
VirtIO9PProxy::writeAll
void writeAll(const uint8_t *data, size_t len)
Convenience function that writes exactly len bytes.
Definition: fs9p.cc:297
VirtIO9PSocket::fdSocket
int fdSocket
Socket connected to the 9p server.
Definition: fs9p.hh:379
VirtIO9PBase::Params
VirtIO9PBaseParams Params
Definition: fs9p.hh:110
VirtDescriptor::chainWrite
void chainWrite(size_t offset, const uint8_t *src, size_t size)
Write to a descriptor chain.
Definition: base.cc:191
VirtIO9PBase::queue
FSQueue queue
Definition: fs9p.hh:161
P9MsgHeader
Definition: fs9p.hh:53
VirtIO9PProxy::~VirtIO9PProxy
virtual ~VirtIO9PProxy()
Definition: fs9p.cc:217
VirtIO9PBase
This class implements a VirtIO transport layer for the 9p network file system.
Definition: fs9p.hh:107
p9_msg_info
static const P9MsgInfoMap p9_msg_info
Definition: fs9p.cc:76
VirtIO9PBase::sendRMsg
void sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)
Send a 9p RPC message reply.
Definition: fs9p.cc:164
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
SimObject::params
const Params * params() const
Definition: sim_object.hh:119
p9toh
T p9toh(T v)
Convert p9 byte order (LE) to host byte order.
Definition: fs9p.hh:64
P9MsgHeader::len
uint32_t len
Length including header.
Definition: fs9p.hh:55
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:233
VirtIO9PBase::FSQueue::onNotifyDescriptor
void onNotifyDescriptor(VirtDescriptor *desc)
Notify queue of pending incoming descriptor.
Definition: fs9p.cc:141
VirtIO9PDiod::DiodDataEvent::parent
VirtIO9PDiod & parent
Definition: fs9p.hh:322
VirtIO9PProxy
VirtIO 9p proxy base class.
Definition: fs9p.hh:211
VirtIO9PSocket::socketDisconnect
void socketDisconnect()
9p server disconnect notification
Definition: fs9p.cc:541
P9MsgInfo
Definition: fs9p.cc:62
inform
#define inform(...)
Definition: logging.hh:240
VirtDescriptor::chainRead
void chainRead(size_t offset, uint8_t *dst, size_t size) const
Read the contents of a descriptor chain.
Definition: base.cc:168
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
ArmISA::len
Bitfield< 18, 16 > len
Definition: miscregs_types.hh:439
VirtIO9PDiod::diod_pid
int diod_pid
PID of diod process.
Definition: fs9p.hh:333
VirtIO9PSocket
VirtIO 9p proxy that communicates with a 9p server over tcp sockets.
Definition: fs9p.hh:342
VirtDescriptor::isOutgoing
bool isOutgoing() const
Check if this is a write-only descriptor (outgoing data).
Definition: base.hh:221
VirtIO9PBase::recvTMsg
virtual void recvTMsg(const P9MsgHeader &header, const uint8_t *data, size_t size)=0
Handle incoming 9p RPC message.
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
P9MsgInfo::P9MsgInfo
P9MsgInfo(P9MsgType _type, std::string _name)
Definition: fs9p.cc:63
P9MsgType
uint8_t P9MsgType
Definition: fs9p.hh:48
simout
OutputDirectory simout
Definition: output.cc:61
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
VirtIODeviceBase::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: base.cc:341
VirtIO9PProxy::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: fs9p.cc:223
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
VirtIO9PSocket::SocketDataEvent::parent
VirtIO9PSocket & parent
Definition: fs9p.hh:375
VirtIO9PDiod::write
ssize_t write(const uint8_t *data, size_t len)
Write data to the server behind the proxy.
Definition: fs9p.cc:424
VirtIO9PSocket::SocketDataEvent
Definition: fs9p.hh:364
CheckpointIn
Definition: serialize.hh:67
VirtIO9PDiod::startup
void startup()
startup() is the final initialization call before simulation.
Definition: fs9p.cc:326
P9MsgInfo::name
std::string name
Definition: fs9p.cc:67
VirtIODeviceBase::kick
void kick()
Inform the guest of available buffers.
Definition: base.hh:609
VirtIO9PDiod::~VirtIO9PDiod
virtual ~VirtIO9PDiod()
Definition: fs9p.cc:321
VirtIO9PBase::Config
VirtIO 9p configuration structure.
Definition: fs9p.hh:123
VirtIO9PSocket::connectSocket
void connectSocket()
Try to resolve the server name and connect to the 9p server.
Definition: fs9p.cc:504
VirtIODeviceBase::byteOrder
ByteOrder byteOrder
The byte order of the queues, descriptors, etc.
Definition: base.hh:718
VirtIO9PDiod::read
ssize_t read(uint8_t *data, size_t len)
Read data from the server behind the proxy.
Definition: fs9p.cc:416
callback.hh
VirtDescriptor::next
VirtDescriptor * next() const
Get the pointer to the next descriptor in a chain.
Definition: base.cc:134
VirtIO9PBase::config
std::unique_ptr< Config > config
Currently active configuration (host byte order)
Definition: fs9p.hh:129
VirtDescriptor
VirtIO descriptor (chain) wrapper.
Definition: base.hh:106
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171

Generated on Wed Sep 30 2020 14:02:11 for gem5 by doxygen 1.8.17