fs9p.cc (12076:d6fa15da87cd) fs9p.cc (12187:21448d4fdaae)
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

--- 31 unchanged lines hidden (view full) ---

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>
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

--- 31 unchanged lines hidden (view full) ---

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>
48#include <unistd.h>
49
49#include <unistd.h>
50
51#include <csignal>
50#include <fstream>
51
52#include <fstream>
53
54#include "base/callback.hh"
52#include "base/output.hh"
53#include "debug/VIO9P.hh"
54#include "debug/VIO9PData.hh"
55#include "params/VirtIO9PBase.hh"
56#include "params/VirtIO9PDiod.hh"
57#include "params/VirtIO9PProxy.hh"
58#include "params/VirtIO9PSocket.hh"
59#include "sim/system.hh"

--- 248 unchanged lines hidden (view full) ---

308}
309
310
311
312VirtIO9PDiod::VirtIO9PDiod(Params *params)
313 : VirtIO9PProxy(params),
314 fd_to_diod(-1), fd_from_diod(-1), diod_pid(-1)
315{
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"

--- 248 unchanged lines hidden (view full) ---

311}
312
313
314
315VirtIO9PDiod::VirtIO9PDiod(Params *params)
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
320 Callback* cb = new MakeCallback<VirtIO9PDiod,
321 &VirtIO9PDiod::terminateDiod>(this);
322 registerExitCallback(cb);
316}
317
318VirtIO9PDiod::~VirtIO9PDiod()
319{
320}
321
322void
323VirtIO9PDiod::startup()

--- 17 unchanged lines hidden (view full) ---

341 DPRINTF(VIO9P, "Using diod at %s \n", p->diod.c_str());
342
343 if (pipe(pipe_rfd) == -1 || pipe(pipe_wfd) == -1)
344 panic("Failed to create DIOD pipes: %i\n", errno);
345
346 fd_to_diod = pipe_rfd[1];
347 fd_from_diod = pipe_wfd[0];
348
323}
324
325VirtIO9PDiod::~VirtIO9PDiod()
326{
327}
328
329void
330VirtIO9PDiod::startup()

--- 17 unchanged lines hidden (view full) ---

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));
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
349 diod_pid = fork();
350 if (diod_pid == -1) {
351 panic("Fork failed: %i\n", errno);
352 } else if (diod_pid == 0) {
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
353 close(STDIN_FILENO);
387 close(STDIN_FILENO);
354
355 if (dup2(pipe_rfd[0], DIOD_RFD) == -1 ||
356 dup2(pipe_wfd[1], DIOD_WFD) == -1) {
357
358 panic("Failed to setup read/write pipes: %i\n",
359 errno);
360 }
361
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
362 // Create Unix domain socket
363 int socket_id = socket(AF_UNIX, SOCK_STREAM, 0);
364 if (socket_id == -1) {
365 panic("Socket creation failed %i \n", errno);
366 }
367 // Bind the socket to a path which will not be read
368 struct sockaddr_un socket_address;
369 memset(&socket_address, 0, sizeof(struct sockaddr_un));
370 socket_address.sun_family = AF_UNIX;
371
372 const std::string socket_path = simout.resolve(p->socketPath);
373 fatal_if(!OutputDirectory::isAbsolute(socket_path), "Please make the" \
374 " output directory an absolute path, else diod will fail!\n");
375
376 // Prevent overflow in strcpy
377 fatal_if(sizeof(socket_address.sun_path) <= socket_path.length(),
378 "Incorrect length of socket path");
379 strncpy(socket_address.sun_path, socket_path.c_str(),
380 sizeof(socket_address.sun_path));
381
382 if (bind(socket_id, (struct sockaddr*) &socket_address,
383 sizeof(struct sockaddr_un)) == -1){
384 perror("Socket binding");
385 panic("Socket binding to %i failed - most likely the output dir" \
386 " and hence unused socket already exists \n", socket_id);
387 }
388
395 // Start diod
389 execlp(diod, diod,
390 "-f", // start in foreground
391 "-r", "3", // setup read FD
392 "-w", "4", // setup write FD
393 "-e", p->root.c_str(), // path to export
394 "-n", // disable security
395 "-S", // squash all users
396 "-l", socket_path.c_str(), // pass the socket
397 (char *)NULL);
398 perror("Starting DIOD");
399 panic("Failed to execute diod to %s: %i\n",socket_path, errno);
400 } else {
401 close(pipe_rfd[0]);
402 close(pipe_wfd[1]);
396 execlp(diod, diod,
397 "-f", // start in foreground
398 "-r", "3", // setup read FD
399 "-w", "4", // setup write FD
400 "-e", p->root.c_str(), // path to export
401 "-n", // disable security
402 "-S", // squash all users
403 "-l", socket_path.c_str(), // pass the socket
404 (char *)NULL);
405 perror("Starting DIOD");
406 panic("Failed to execute diod to %s: %i\n",socket_path, errno);
407 } else {
408 close(pipe_rfd[0]);
409 close(pipe_wfd[1]);
410 inform("Started diod with PID %u, you might need to manually kill " \
411 " diod if gem5 crashes \n", diod_pid);
403 }
404
405#undef DIOD_RFD
406#undef DIOD_WFD
407}
408
409ssize_t
410VirtIO9PDiod::read(uint8_t *data, size_t len)

--- 12 unchanged lines hidden (view full) ---

423}
424
425void
426VirtIO9PDiod::DiodDataEvent::process(int revent)
427{
428 parent.serverDataReady();
429}
430
412 }
413
414#undef DIOD_RFD
415#undef DIOD_WFD
416}
417
418ssize_t
419VirtIO9PDiod::read(uint8_t *data, size_t len)

--- 12 unchanged lines hidden (view full) ---

432}
433
434void
435VirtIO9PDiod::DiodDataEvent::process(int revent)
436{
437 parent.serverDataReady();
438}
439
440void
441VirtIO9PDiod::terminateDiod()
442{
443 assert(diod_pid != -1);
444
445 DPRINTF(VIO9P, "Trying to kill diod at pid %u \n", diod_pid);
446
447 if (kill(diod_pid, SIGTERM) != 0) {
448 perror("Killing diod process");
449 warn("Failed to kill diod using SIGTERM");
450 return;
451 }
452
453 // Check if kill worked
454 for (unsigned i = 0; i < 5; i++) {
455 int wait_return = waitpid(diod_pid, NULL, WNOHANG);
456 if (wait_return == diod_pid) {
457 // Managed to kill diod
458 return;
459 } else if (wait_return == 0) {
460 // Diod is not killed so sleep and try again
461 usleep(500);
462 } else {
463 // Failed in waitpid
464 perror("Waitpid");
465 warn("Failed in waitpid");
466 }
467 }
468
469 // Try again to kill diod with sigkill
470 inform("Trying to kill diod with SIGKILL as SIGTERM failed \n");
471 if (kill(diod_pid, SIGKILL) != 0) {
472 perror("Killing diod process");
473 warn("Failed to kill diod using SIGKILL");
474 } else {
475 // Managed to kill diod
476 return;
477 }
478
479}
431VirtIO9PDiod *
432VirtIO9PDiodParams::create()
433{
434 return new VirtIO9PDiod(this);
435}
436
437
438

--- 94 unchanged lines hidden ---
480VirtIO9PDiod *
481VirtIO9PDiodParams::create()
482{
483 return new VirtIO9PDiod(this);
484}
485
486
487

--- 94 unchanged lines hidden ---