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

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13