Allow chardev of type 'file' for UML domains.

Like the comment suggested, we just open the file and pass the file
descriptor to uml. The input "stream" is set to "null", since I couldn't
find any useful way to actually use a file for input for a chardev and
this also mimics what e.g. QEmu does internally.

Signed-off-by: Soren Hansen <soren@linux2go.dk>
This commit is contained in:
Soren Hansen 2010-08-23 13:25:50 +02:00 committed by Matthias Bolte
parent 8c48743b97
commit 21dcce5364
3 changed files with 36 additions and 6 deletions

View File

@ -295,7 +295,8 @@ error:
static char *
umlBuildCommandLineChr(virDomainChrDefPtr def,
const char *dev)
const char *dev,
fd_set *keepfd)
{
char *ret = NULL;
@ -344,8 +345,27 @@ umlBuildCommandLineChr(virDomainChrDefPtr def,
break;
case VIR_DOMAIN_CHR_TYPE_FILE:
{
int fd_out;
if ((fd_out = open(def->data.file.path,
O_WRONLY | O_APPEND | O_CREAT, 0660)) < 0) {
virReportSystemError(errno,
_("failed to open chardev file: %s"),
def->data.file.path);
return NULL;
}
if (virAsprintf(&ret, "%s%d=null,fd:%d", dev, def->target.port, fd_out) < 0) {
virReportOOMError();
close(fd_out);
return NULL;
}
FD_SET(fd_out, keepfd);
}
break;
case VIR_DOMAIN_CHR_TYPE_PIPE:
/* XXX could open the file/pipe & just pass the FDs */
/* XXX could open the pipe & just pass the FDs. Be wary of
* the effects of blocking I/O, though. */
case VIR_DOMAIN_CHR_TYPE_VC:
case VIR_DOMAIN_CHR_TYPE_UDP:
@ -391,6 +411,7 @@ static char *umlNextArg(char *args)
int umlBuildCommandLine(virConnectPtr conn,
struct uml_driver *driver ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
fd_set *keepfd,
const char ***retargv,
const char ***retenv)
{
@ -513,7 +534,7 @@ int umlBuildCommandLine(virConnectPtr conn,
for (i = 0 ; i < UML_MAX_CHAR_DEVICE ; i++) {
char *ret = NULL;
if (i == 0 && vm->def->console)
ret = umlBuildCommandLineChr(vm->def->console, "con");
ret = umlBuildCommandLineChr(vm->def->console, "con", keepfd);
if (!ret)
if (virAsprintf(&ret, "con%d=none", i) < 0)
goto no_memory;
@ -527,7 +548,7 @@ int umlBuildCommandLine(virConnectPtr conn,
if (vm->def->serials[j]->target.port == i)
chr = vm->def->serials[j];
if (chr)
ret = umlBuildCommandLineChr(chr, "ssl");
ret = umlBuildCommandLineChr(chr, "ssl", keepfd);
if (!ret)
if (virAsprintf(&ret, "ssl%d=none", i) < 0)
goto no_memory;

View File

@ -71,6 +71,7 @@ virCapsPtr umlCapsInit (void);
int umlBuildCommandLine (virConnectPtr conn,
struct uml_driver *driver,
virDomainObjPtr dom,
fd_set *keepfd,
const char ***retargv,
const char ***retenv);

View File

@ -869,7 +869,7 @@ static int umlStartVMDaemon(virConnectPtr conn,
return -1;
}
if (umlBuildCommandLine(conn, driver, vm,
if (umlBuildCommandLine(conn, driver, vm, &keepfd,
&argv, &progenv) < 0) {
close(logfd);
umlCleanupTapDevices(conn, vm);
@ -908,6 +908,14 @@ static int umlStartVMDaemon(virConnectPtr conn,
NULL, NULL, NULL);
close(logfd);
/*
* At the moment, the only thing that populates keepfd is
* umlBuildCommandLineChr. We want to close every fd it opens.
*/
for (i = 0; i < FD_SETSIZE; i++)
if (FD_ISSET(i, &keepfd))
close(i);
for (i = 0 ; argv[i] ; i++)
VIR_FREE(argv[i]);
VIR_FREE(argv);