virDomainObj *vm;
virDomainDef *def;
- int handshakeFd;
+ int handshakeFds[2]; /* { read FD, write FD } */
pid_t initpid;
ctrl->timerShutdown = -1;
ctrl->firstClient = true;
ctrl->name = g_strdup(name);
- ctrl->handshakeFd = -1;
+ ctrl->handshakeFds[0] = -1;
+ ctrl->handshakeFds[1] = -1;
if (!(driver = virLXCControllerDriverNew()))
goto error;
virCgroupFree(ctrl->cgroup);
/* This must always be the last thing to be closed */
- VIR_FORCE_CLOSE(ctrl->handshakeFd);
+ for (i = 0; i < G_N_ELEMENTS(ctrl->handshakeFds); i++)
+ VIR_FORCE_CLOSE(ctrl->handshakeFds[i]);
g_free(ctrl);
}
static int virLXCControllerDaemonHandshake(virLXCController *ctrl)
{
- if (lxcContainerSendContinue(ctrl->handshakeFd) < 0) {
+ if (lxcContainerSendContinue(ctrl->handshakeFds[1]) < 0) {
virReportSystemError(errno, "%s",
_("error sending continue signal to daemon"));
return -1;
if (virLXCControllerDaemonHandshake(ctrl) < 0)
goto cleanup;
- /* and preemptively close handshakeFd */
- VIR_FORCE_CLOSE(ctrl->handshakeFd);
+ /* and preemptively close handshakeFds */
+ for (i = 0; i < G_N_ELEMENTS(ctrl->handshakeFds); i++)
+ VIR_FORCE_CLOSE(ctrl->handshakeFds[i]);
/* We must not hold open a dbus connection for life
* of LXC instance, since dbus-daemon is limited to
}
+static int
+parseFDPair(const char *arg,
+ int (*fd)[2])
+{
+ g_auto(GStrv) fds = NULL;
+
+ fds = g_strsplit(arg, ":", 0);
+
+ if (fds[0] == NULL || fds[1] == NULL || fds[2] != NULL ||
+ virStrToLong_i(fds[0], NULL, 10, &(*fd)[0]) < 0 ||
+ virStrToLong_i(fds[1], NULL, 10, &(*fd)[1]) < 0) {
+ fprintf(stderr, "malformed --handshakefds argument '%s'",
+ optarg);
+ return -1;
+ }
+
+ return 0;
+}
+
+
int main(int argc, char *argv[])
{
pid_t pid;
size_t nveths = 0;
char **veths = NULL;
int ns_fd[VIR_LXC_DOMAIN_NAMESPACE_LAST];
- int handshakeFd = -1;
+ int handshakeFds[2] = { -1, -1 };
bool bg = false;
const struct option options[] = {
{ "background", 0, NULL, 'b' },
{ "veth", 1, NULL, 'v' },
{ "console", 1, NULL, 'c' },
{ "passfd", 1, NULL, 'p' },
- { "handshakefd", 1, NULL, 's' },
+ { "handshakefds", 1, NULL, 's' },
{ "security", 1, NULL, 'S' },
{ "share-net", 1, NULL, 'N' },
{ "share-ipc", 1, NULL, 'I' },
break;
case 's':
- if (virStrToLong_i(optarg, NULL, 10, &handshakeFd) < 0) {
- fprintf(stderr, "malformed --handshakefd argument '%s'",
- optarg);
+ if (parseFDPair(optarg, &handshakeFds) < 0)
goto cleanup;
- }
break;
case 'N':
fprintf(stderr, " -n NAME, --name NAME\n");
fprintf(stderr, " -c FD, --console FD\n");
fprintf(stderr, " -v VETH, --veth VETH\n");
- fprintf(stderr, " -s FD, --handshakefd FD\n");
+ fprintf(stderr, " -s FD:FD, --handshakefds FD:FD (read:write)\n");
fprintf(stderr, " -S NAME, --security NAME\n");
fprintf(stderr, " -N FD, --share-net FD\n");
fprintf(stderr, " -I FD, --share-ipc FD\n");
goto cleanup;
}
- if (handshakeFd < 0) {
- fprintf(stderr, "%s: missing --handshakefd argument for container PTY\n",
+ if (handshakeFds[0] < 0 || handshakeFds[1] < 0) {
+ fprintf(stderr, "%s: missing --handshakefds argument for container PTY\n",
argv[0]);
goto cleanup;
}
if (!(ctrl = virLXCControllerNew(name)))
goto cleanup;
- ctrl->handshakeFd = handshakeFd;
+ memcpy(&ctrl->handshakeFds, &handshakeFds, sizeof(handshakeFds));
if (!(ctrl->securityManager = virSecurityManagerNew(securityDriver,
LXC_DRIVER_NAME, 0)))
int *nsInheritFDs,
int *files,
size_t nfiles,
- int handshakefd,
+ int handshakefdW,
+ int handshakefdR,
int * const logfd,
const char *pidfile)
{
virCommandAddArgPair(cmd, "--security",
virSecurityManagerGetModel(driver->securityManager));
- virCommandAddArg(cmd, "--handshakefd");
- virCommandAddArgFormat(cmd, "%d", handshakefd);
+ virCommandAddArg(cmd, "--handshakefds");
+ virCommandAddArgFormat(cmd, "%d:%d", handshakefdR, handshakefdW);
for (i = 0; veths && veths[i]; i++)
virCommandAddArgList(cmd, "--veth", veths[i], NULL);
- virCommandPassFD(cmd, handshakefd, 0);
+ virCommandPassFD(cmd, handshakefdW, 0);
+ virCommandPassFD(cmd, handshakefdR, 0);
virCommandDaemonize(cmd);
virCommandSetPidFile(cmd, pidfile);
virCommandSetOutputFD(cmd, logfd);
g_autofree char *logfile = NULL;
int logfd = -1;
g_auto(GStrv) veths = NULL;
- int handshakefds[2] = { -1, -1 };
+ int handshakefds[4] = { -1, -1, -1, -1 }; /* two pipes */
off_t pos = -1;
char ebuf[1024];
g_autofree char *timestamp = NULL;
goto cleanup;
}
- if (virPipe(handshakefds) < 0)
+ if (virPipe(&handshakefds[0]) < 0 ||
+ virPipe(&handshakefds[2]) < 0)
goto cleanup;
if (!(cmd = virLXCProcessBuildControllerCmd(driver,
nsInheritFDs,
files, nfiles,
handshakefds[1],
+ handshakefds[2],
&logfd,
pidfile)))
goto cleanup;
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
priv->doneStopEvent = false;
- if (VIR_CLOSE(handshakefds[1]) < 0) {
+ if (VIR_CLOSE(handshakefds[1]) < 0 ||
+ VIR_CLOSE(handshakefds[2]) < 0) {
virReportSystemError(errno, "%s", _("could not close handshake fd"));
goto cleanup;
}
virCommandFree(cmd);
for (i = 0; i < nttyFDs; i++)
VIR_FORCE_CLOSE(ttyFDs[i]);
- VIR_FORCE_CLOSE(handshakefds[0]);
- VIR_FORCE_CLOSE(handshakefds[1]);
+ for (i = 0; i < G_N_ELEMENTS(handshakefds); i++)
+ VIR_FORCE_CLOSE(handshakefds[i]);
virObjectUnref(cfg);
virObjectUnref(caps);