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