test: Make nstool hold robust against interruptions to control clients
Currently nstool die()s on essentially any error. In most cases that's fine for our purposes. However, it's a problem when in "hold" mode and getting an IO error on an accept()ed socket. This could just indicate that the control client aborted prematurely, in which case we don't want to kill of the namespace we're holding. Adjust these to print an error, close() the control client socket and carry on. In addition, we need to explicitly ignore SIGPIPE in order not to be killed by an abruptly closed client connection. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
b456ee1b53
commit
1699083f29
1 changed files with 26 additions and 10 deletions
|
@ -33,10 +33,15 @@
|
||||||
|
|
||||||
#define die(...) \
|
#define die(...) \
|
||||||
do { \
|
do { \
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, "nstool: " __VA_ARGS__); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define err(...) \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr, "nstool: " __VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
struct ns_type {
|
struct ns_type {
|
||||||
int flag;
|
int flag;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -156,6 +161,9 @@ static int connect_ctl(const char *sockpath, bool wait,
|
||||||
|
|
||||||
static void cmd_hold(int argc, char *argv[])
|
static void cmd_hold(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
struct sigaction sa = {
|
||||||
|
.sa_handler = SIG_IGN,
|
||||||
|
};
|
||||||
int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNIX);
|
int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNIX);
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
const char *sockpath = argv[1];
|
const char *sockpath = argv[1];
|
||||||
|
@ -185,6 +193,10 @@ static void cmd_hold(int argc, char *argv[])
|
||||||
if (!getcwd(info.cwd, sizeof(info.cwd)))
|
if (!getcwd(info.cwd, sizeof(info.cwd)))
|
||||||
die("getcwd(): %s\n", strerror(errno));
|
die("getcwd(): %s\n", strerror(errno));
|
||||||
|
|
||||||
|
rc = sigaction(SIGPIPE, &sa, NULL);
|
||||||
|
if (rc)
|
||||||
|
die("sigaction(SIGPIPE): %s\n", strerror(errno));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int afd = accept(fd, NULL, NULL);
|
int afd = accept(fd, NULL, NULL);
|
||||||
char buf;
|
char buf;
|
||||||
|
@ -193,17 +205,21 @@ static void cmd_hold(int argc, char *argv[])
|
||||||
die("accept(): %s\n", strerror(errno));
|
die("accept(): %s\n", strerror(errno));
|
||||||
|
|
||||||
rc = write(afd, &info, sizeof(info));
|
rc = write(afd, &info, sizeof(info));
|
||||||
if (rc < 0)
|
if (rc < 0) {
|
||||||
die("write(): %s\n", strerror(errno));
|
err("holder write() to control socket: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
if ((size_t)rc < sizeof(info))
|
if ((size_t)rc < sizeof(info))
|
||||||
die("short write() on control socket\n");
|
err("holder short write() on control socket\n");
|
||||||
|
|
||||||
rc = read(afd, &buf, sizeof(buf));
|
rc = read(afd, &buf, sizeof(buf));
|
||||||
if (rc < 0)
|
if (rc < 0) {
|
||||||
die("read(): %s\n", strerror(errno));
|
err("holder read() on control socket: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
close(afd);
|
close(afd);
|
||||||
} while (rc == 0);
|
} while (rc <= 0);
|
||||||
|
|
||||||
unlink(sockpath);
|
unlink(sockpath);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue