mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-08 12:41:29 +00:00
* src/Makefile.am src/openvz_conf.c src/openvz_conf.h
src/openvz_driver.c src/qemu_driver.c src/util.c src/util.h: cleanup patches from Shuveb Hussain, with new util module for common code shared between drivers. Daniel
This commit is contained in:
parent
e2ea955881
commit
68ef3443d4
@ -1,3 +1,10 @@
|
|||||||
|
Thu Jul 19 18:21:47 CEST 2007 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* src/Makefile.am src/openvz_conf.c src/openvz_conf.h
|
||||||
|
src/openvz_driver.c src/qemu_driver.c src/util.c src/util.h:
|
||||||
|
cleanup patches from Shuveb Hussain, with new util module for
|
||||||
|
common code shared between drivers.
|
||||||
|
|
||||||
Thu Jul 19 16:35:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
|
Thu Jul 19 16:35:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
|
||||||
|
|
||||||
* configure.in, src/xen_internal.c: Newer Xen uses
|
* configure.in, src/xen_internal.c: Newer Xen uses
|
||||||
|
@ -51,6 +51,7 @@ typedef enum {
|
|||||||
VIR_FROM_NET, /* Error when operating on a network */
|
VIR_FROM_NET, /* Error when operating on a network */
|
||||||
VIR_FROM_TEST, /* Error from test driver */
|
VIR_FROM_TEST, /* Error from test driver */
|
||||||
VIR_FROM_REMOTE, /* Error from remote driver */
|
VIR_FROM_REMOTE, /* Error from remote driver */
|
||||||
|
VIR_FROM_OPENVZ, /* Error from OpenVZ driver */
|
||||||
} virErrorDomain;
|
} virErrorDomain;
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ CLIENT_SOURCES = \
|
|||||||
qemu_driver.c qemu_driver.h \
|
qemu_driver.c qemu_driver.h \
|
||||||
qemu_conf.c qemu_conf.h \
|
qemu_conf.c qemu_conf.h \
|
||||||
openvz_conf.c openvz_conf.h \
|
openvz_conf.c openvz_conf.h \
|
||||||
openvz_driver.c openvz_driver.h
|
openvz_driver.c openvz_driver.h \
|
||||||
|
util.c util.h
|
||||||
|
|
||||||
SERVER_SOURCES = \
|
SERVER_SOURCES = \
|
||||||
../qemud/protocol.h ../qemud/protocol.c \
|
../qemud/protocol.h ../qemud/protocol.c \
|
||||||
|
@ -57,7 +57,8 @@ error (virConnectPtr conn, virErrorNumber code, const char *info)
|
|||||||
errmsg, info);
|
errmsg, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct openvz_vm *openvzFindVMByID(const struct openvz_driver *driver, int id) {
|
struct openvz_vm
|
||||||
|
*openvzFindVMByID(const struct openvz_driver *driver, int id) {
|
||||||
struct openvz_vm *vm = driver->vms;
|
struct openvz_vm *vm = driver->vms;
|
||||||
|
|
||||||
while (vm) {
|
while (vm) {
|
||||||
@ -69,7 +70,8 @@ struct openvz_vm *openvzFindVMByID(const struct openvz_driver *driver, int id) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct openvz_vm *openvzFindVMByUUID(const struct openvz_driver *driver,
|
struct openvz_vm
|
||||||
|
*openvzFindVMByUUID(const struct openvz_driver *driver,
|
||||||
const unsigned char *uuid) {
|
const unsigned char *uuid) {
|
||||||
struct openvz_vm *vm = driver->vms;
|
struct openvz_vm *vm = driver->vms;
|
||||||
|
|
||||||
@ -82,7 +84,8 @@ struct openvz_vm *openvzFindVMByUUID(const struct openvz_driver *driver,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct openvz_vm *openvzFindVMByName(const struct openvz_driver *driver,
|
struct openvz_vm
|
||||||
|
*openvzFindVMByName(const struct openvz_driver *driver,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
struct openvz_vm *vm = driver->vms;
|
struct openvz_vm *vm = driver->vms;
|
||||||
|
|
||||||
@ -96,7 +99,8 @@ struct openvz_vm *openvzFindVMByName(const struct openvz_driver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free all memory associated with a struct openvz_vm object */
|
/* Free all memory associated with a struct openvz_vm object */
|
||||||
void openvzFreeVMDef(struct openvz_vm_def *def) {
|
void
|
||||||
|
openvzFreeVMDef(struct openvz_vm_def *def) {
|
||||||
struct ovz_quota *quota = def->fs.quota;
|
struct ovz_quota *quota = def->fs.quota;
|
||||||
struct ovz_ip *ip = def->net.ips;
|
struct ovz_ip *ip = def->net.ips;
|
||||||
struct ovz_ns *ns = def->net.ns;
|
struct ovz_ns *ns = def->net.ns;
|
||||||
@ -124,8 +128,9 @@ void openvzFreeVMDef(struct openvz_vm_def *def) {
|
|||||||
* Parses a libvirt XML definition of a guest, and populates the
|
* Parses a libvirt XML definition of a guest, and populates the
|
||||||
* the openvz_vm struct with matching data about the guests config
|
* the openvz_vm struct with matching data about the guests config
|
||||||
*/
|
*/
|
||||||
static struct openvz_vm_def *openvzParseXML(virConnectPtr conn,
|
static struct openvz_vm_def
|
||||||
xmlDocPtr xml) {
|
*openvzParseXML(virConnectPtr conn,
|
||||||
|
xmlDocPtr xml) {
|
||||||
xmlNodePtr root = NULL;
|
xmlNodePtr root = NULL;
|
||||||
xmlChar *prop = NULL;
|
xmlChar *prop = NULL;
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
@ -249,7 +254,7 @@ openvzGetVPSInfo(virConnectPtr conn) {
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
int veid, ret;
|
int veid, ret;
|
||||||
char status[16];
|
char status[16];
|
||||||
char uuidstr[(VIR_UUID_BUFLEN * 2) + 1];
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
struct openvz_vm *vm;
|
struct openvz_vm *vm;
|
||||||
struct openvz_vm **pnext;
|
struct openvz_vm **pnext;
|
||||||
struct openvz_driver *driver;
|
struct openvz_driver *driver;
|
||||||
@ -296,15 +301,9 @@ openvzGetVPSInfo(virConnectPtr conn) {
|
|||||||
|
|
||||||
snprintf(vmdef->name, OPENVZ_NAME_MAX, "%i", veid);
|
snprintf(vmdef->name, OPENVZ_NAME_MAX, "%i", veid);
|
||||||
openvzGetVPSUUID(veid, uuidstr);
|
openvzGetVPSUUID(veid, uuidstr);
|
||||||
ret = sscanf(uuidstr, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
ret = virUUIDParse(uuidstr, vmdef->uuid);
|
||||||
(unsigned int *)&vmdef->uuid[0], (unsigned int *)&vmdef->uuid[1], (unsigned int *)&vmdef->uuid[2],
|
|
||||||
(unsigned int *)&vmdef->uuid[3], (unsigned int *)&vmdef->uuid[4], (unsigned int *)&vmdef->uuid[5],
|
|
||||||
(unsigned int *)&vmdef->uuid[6], (unsigned int *)&vmdef->uuid[7], (unsigned int *)&vmdef->uuid[8],
|
|
||||||
(unsigned int *)&vmdef->uuid[9], (unsigned int *)&vmdef->uuid[10], (unsigned int *)&vmdef->uuid[11],
|
|
||||||
(unsigned int *)&vmdef->uuid[12], (unsigned int *)&vmdef->uuid[13], (unsigned int *)&vmdef->uuid[14],
|
|
||||||
(unsigned int *)&vmdef->uuid[15]);
|
|
||||||
|
|
||||||
if(ret != 16) {
|
if(ret == -1) {
|
||||||
error(conn, VIR_ERR_INTERNAL_ERROR, "UUID in config file malformed");
|
error(conn, VIR_ERR_INTERNAL_ERROR, "UUID in config file malformed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -315,7 +314,8 @@ openvzGetVPSInfo(virConnectPtr conn) {
|
|||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *openvzLocateConfDir(void)
|
static char
|
||||||
|
*openvzLocateConfDir(void)
|
||||||
{
|
{
|
||||||
const char *conf_dir_list[] = {"/etc/vz/conf", "/usr/local/etc/conf", NULL};
|
const char *conf_dir_list[] = {"/etc/vz/conf", "/usr/local/etc/conf", NULL};
|
||||||
int i=0;
|
int i=0;
|
||||||
@ -330,9 +330,8 @@ char *openvzLocateConfDir(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Richard Steven's classic readline() function */
|
/* Richard Steven's classic readline() function */
|
||||||
|
int
|
||||||
static
|
openvz_readline(int fd, char *ptr, int maxlen)
|
||||||
int openvz_readline(int fd, char *ptr, int maxlen)
|
|
||||||
{
|
{
|
||||||
int n, rc;
|
int n, rc;
|
||||||
char c;
|
char c;
|
||||||
@ -356,7 +355,8 @@ int openvz_readline(int fd, char *ptr, int maxlen)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int openvzGetVPSUUID(int vpsid, char *uuidbuf)
|
static int
|
||||||
|
openvzGetVPSUUID(int vpsid, char *uuidbuf)
|
||||||
{
|
{
|
||||||
char conf_file[PATH_MAX];
|
char conf_file[PATH_MAX];
|
||||||
char line[1024];
|
char line[1024];
|
||||||
@ -385,7 +385,7 @@ int openvzGetVPSUUID(int vpsid, char *uuidbuf)
|
|||||||
|
|
||||||
sscanf(line, "%s %s\n", iden, uuid);
|
sscanf(line, "%s %s\n", iden, uuid);
|
||||||
if(!strcmp(iden, "#UUID:")) {
|
if(!strcmp(iden, "#UUID:")) {
|
||||||
strncpy(uuidbuf, uuid, (VIR_UUID_BUFLEN * 2) +1);
|
strncpy(uuidbuf, uuid, VIR_UUID_STRING_BUFLEN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,10 +396,11 @@ int openvzGetVPSUUID(int vpsid, char *uuidbuf)
|
|||||||
* assign if not present.
|
* assign if not present.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int openvzSetUUID(int vpsid)
|
static int
|
||||||
|
openvzSetUUID(int vpsid)
|
||||||
{
|
{
|
||||||
char conf_file[PATH_MAX];
|
char conf_file[PATH_MAX];
|
||||||
char uuid[(VIR_UUID_BUFLEN * 2) + 1];
|
char uuid[VIR_UUID_STRING_BUFLEN];
|
||||||
unsigned char new_uuid[VIR_UUID_BUFLEN];
|
unsigned char new_uuid[VIR_UUID_BUFLEN];
|
||||||
char *conf_dir;
|
char *conf_dir;
|
||||||
int fd, ret, i;
|
int fd, ret, i;
|
||||||
@ -418,7 +419,7 @@ int openvzSetUUID(int vpsid)
|
|||||||
|
|
||||||
if(uuid[0] == (int)NULL) {
|
if(uuid[0] == (int)NULL) {
|
||||||
virUUIDGenerate(new_uuid);
|
virUUIDGenerate(new_uuid);
|
||||||
bzero(uuid, (VIR_UUID_BUFLEN * 2) + 1);
|
bzero(uuid, VIR_UUID_STRING_BUFLEN);
|
||||||
for(i = 0; i < VIR_UUID_BUFLEN; i ++)
|
for(i = 0; i < VIR_UUID_BUFLEN; i ++)
|
||||||
sprintf(uuid + (i * 2), "%02x", (unsigned char)new_uuid[i]);
|
sprintf(uuid + (i * 2), "%02x", (unsigned char)new_uuid[i]);
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ struct openvz_vm {
|
|||||||
struct openvz_vm *next;
|
struct openvz_vm *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
char *openvzLocateConfDir(void);
|
static char *openvzLocateConfDir(void);
|
||||||
int readline(int fd, char *ptr, int maxlen);
|
int openvz_readline(int fd, char *ptr, int maxlen);
|
||||||
static void error (virConnectPtr conn, virErrorNumber code, const char *info);
|
static void error (virConnectPtr conn, virErrorNumber code, const char *info);
|
||||||
struct openvz_vm *openvzFindVMByID(const struct openvz_driver *driver, int id);
|
struct openvz_vm *openvzFindVMByID(const struct openvz_driver *driver, int id);
|
||||||
struct openvz_vm *openvzFindVMByUUID(const struct openvz_driver *driver,
|
struct openvz_vm *openvzFindVMByUUID(const struct openvz_driver *driver,
|
||||||
@ -108,7 +108,7 @@ struct openvz_vm_def *openvzParseVMDef(virConnectPtr conn, const char *xmlStr,
|
|||||||
const char *displayName);
|
const char *displayName);
|
||||||
struct openvz_vm *openvzGetVPSInfo(virConnectPtr conn);
|
struct openvz_vm *openvzGetVPSInfo(virConnectPtr conn);
|
||||||
void openvzGenerateUUID(unsigned char *uuid);
|
void openvzGenerateUUID(unsigned char *uuid);
|
||||||
int openvzGetVPSUUID(int vpsid, char *uuidbuf);
|
static int openvzGetVPSUUID(int vpsid, char *uuidbuf);
|
||||||
int openvzSetUUID(int vpsid);
|
static int openvzSetUUID(int vpsid);
|
||||||
int openvzAssignUUIDs(void);
|
int openvzAssignUUIDs(void);
|
||||||
#endif /* OPENVZ_CONF_H */
|
#endif /* OPENVZ_CONF_H */
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
|
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
#include "util.h"
|
||||||
#include "openvz_driver.h"
|
#include "openvz_driver.h"
|
||||||
#include "openvz_conf.h"
|
#include "openvz_conf.h"
|
||||||
|
|
||||||
@ -284,6 +285,11 @@ static virDrvOpenStatus openvzOpen(virConnectPtr conn,
|
|||||||
if (strcmp(name, "openvz:///system"))
|
if (strcmp(name, "openvz:///system"))
|
||||||
return VIR_DRV_OPEN_DECLINED;
|
return VIR_DRV_OPEN_DECLINED;
|
||||||
}
|
}
|
||||||
|
/* See if we are running an OpenVZ enabled kernel */
|
||||||
|
if(access("/proc/vz/veinfo", F_OK) == -1 ||
|
||||||
|
access("/proc/user_beancounters", F_OK) == -1) {
|
||||||
|
return VIR_DRV_OPEN_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
conn->privateData = &ovz_driver;
|
conn->privateData = &ovz_driver;
|
||||||
|
|
||||||
@ -323,19 +329,25 @@ static const char *openvzGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
|||||||
|
|
||||||
static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
|
static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
|
||||||
int got = 0;
|
int got = 0;
|
||||||
int veid;
|
int veid, pid, outfd, errfd;
|
||||||
FILE *fp;
|
int ret;
|
||||||
|
char buf[32];
|
||||||
|
const char *cmd[] = {VZLIST, "-ovpsid", "-H" , NULL};
|
||||||
|
|
||||||
if((fp = popen(VZLIST " -o vpsid -H 2> /dev/null", "r")) == NULL){
|
ret = virExec(conn, (char **)cmd, &pid, &outfd, &errfd);
|
||||||
error(conn, VIR_ERR_INTERNAL_ERROR, "Could not popen " VZLIST);
|
if(ret == -1) {
|
||||||
|
error(conn, VIR_ERR_INTERNAL_ERROR, "Could not exec " VZLIST);
|
||||||
return (int)NULL;
|
return (int)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!(feof(fp)) && got < nids){
|
while(got < nids){
|
||||||
fscanf(fp, "%d\n", &veid);
|
ret = openvz_readline(outfd, buf, 32);
|
||||||
|
if(!ret) break;
|
||||||
|
sscanf(buf, "%d", &veid);
|
||||||
ids[got] = veid;
|
ids[got] = veid;
|
||||||
got ++;
|
got ++;
|
||||||
}
|
}
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
@ -347,23 +359,27 @@ static int openvzNumDomains(virConnectPtr conn) {
|
|||||||
static int openvzListDefinedDomains(virConnectPtr conn,
|
static int openvzListDefinedDomains(virConnectPtr conn,
|
||||||
char **const names, int nnames) {
|
char **const names, int nnames) {
|
||||||
int got = 0;
|
int got = 0;
|
||||||
FILE *fp;
|
int veid, pid, outfd, errfd, ret;
|
||||||
int veid;
|
|
||||||
char vpsname[OPENVZ_NAME_MAX];
|
char vpsname[OPENVZ_NAME_MAX];
|
||||||
|
char buf[32];
|
||||||
|
const char *cmd[] = {VZLIST, "-ovpsid", "-H", NULL};
|
||||||
|
|
||||||
/* the -S options lists only stopped domains */
|
/* the -S options lists only stopped domains */
|
||||||
if((fp = popen(VZLIST " -S -o vpsid -H 2> /dev/null", "r")) == NULL){
|
ret = virExec(conn, (char **)cmd, &pid, &outfd, &errfd);
|
||||||
error(conn, VIR_ERR_INTERNAL_ERROR, "Could not popen " VZLIST);
|
if(ret == -1) {
|
||||||
|
error(conn, VIR_ERR_INTERNAL_ERROR, "Could not exec " VZLIST);
|
||||||
return (int)NULL;
|
return (int)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!(feof(fp)) && got < nnames){
|
while(got < nnames){
|
||||||
fscanf(fp, "%d\n", &veid);
|
ret = openvz_readline(outfd, buf, 32);
|
||||||
|
if(!ret) break;
|
||||||
|
sscanf(buf, "%d\n", &veid);
|
||||||
sprintf(vpsname, "%d", veid);
|
sprintf(vpsname, "%d", veid);
|
||||||
names[got] = strdup(vpsname);
|
names[got] = strdup(vpsname);
|
||||||
got ++;
|
got ++;
|
||||||
}
|
}
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
#include "util.h"
|
||||||
#include "qemu_driver.h"
|
#include "qemu_driver.h"
|
||||||
#include "qemu_conf.h"
|
#include "qemu_conf.h"
|
||||||
|
|
||||||
@ -330,91 +331,6 @@ qemudShutdown(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
qemudExec(virConnectPtr conn,
|
|
||||||
char **argv,
|
|
||||||
int *retpid, int *outfd, int *errfd) {
|
|
||||||
int pid, null;
|
|
||||||
int pipeout[2] = {-1,-1};
|
|
||||||
int pipeerr[2] = {-1,-1};
|
|
||||||
|
|
||||||
if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot open %s : %s",
|
|
||||||
_PATH_DEVNULL, strerror(errno));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((outfd != NULL && pipe(pipeout) < 0) ||
|
|
||||||
(errfd != NULL && pipe(pipeerr) < 0)) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot create pipe : %s",
|
|
||||||
strerror(errno));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pid = fork()) < 0) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot fork child process : %s",
|
|
||||||
strerror(errno));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid) { /* parent */
|
|
||||||
close(null);
|
|
||||||
if (outfd) {
|
|
||||||
close(pipeout[1]);
|
|
||||||
qemudSetNonBlock(pipeout[0]);
|
|
||||||
qemudSetCloseExec(pipeout[0]);
|
|
||||||
*outfd = pipeout[0];
|
|
||||||
}
|
|
||||||
if (errfd) {
|
|
||||||
close(pipeerr[1]);
|
|
||||||
qemudSetNonBlock(pipeerr[0]);
|
|
||||||
qemudSetCloseExec(pipeerr[0]);
|
|
||||||
*errfd = pipeerr[0];
|
|
||||||
}
|
|
||||||
*retpid = pid;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* child */
|
|
||||||
|
|
||||||
if (pipeout[0] > 0 && close(pipeout[0]) < 0)
|
|
||||||
_exit(1);
|
|
||||||
if (pipeerr[0] > 0 && close(pipeerr[0]) < 0)
|
|
||||||
_exit(1);
|
|
||||||
|
|
||||||
if (dup2(null, STDIN_FILENO) < 0)
|
|
||||||
_exit(1);
|
|
||||||
if (dup2(pipeout[1] > 0 ? pipeout[1] : null, STDOUT_FILENO) < 0)
|
|
||||||
_exit(1);
|
|
||||||
if (dup2(pipeerr[1] > 0 ? pipeerr[1] : null, STDERR_FILENO) < 0)
|
|
||||||
_exit(1);
|
|
||||||
|
|
||||||
close(null);
|
|
||||||
if (pipeout[1] > 0)
|
|
||||||
close(pipeout[1]);
|
|
||||||
if (pipeerr[1] > 0)
|
|
||||||
close(pipeerr[1]);
|
|
||||||
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
|
|
||||||
_exit(1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (pipeerr[0] > 0)
|
|
||||||
close(pipeerr[0]);
|
|
||||||
if (pipeerr[1] > 0)
|
|
||||||
close(pipeerr[1]);
|
|
||||||
if (pipeout[0] > 0)
|
|
||||||
close(pipeout[0]);
|
|
||||||
if (pipeout[1] > 0)
|
|
||||||
close(pipeout[1]);
|
|
||||||
if (null > 0)
|
|
||||||
close(null);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return -1 for error, 1 to continue reading and 0 for success */
|
/* Return -1 for error, 1 to continue reading and 0 for success */
|
||||||
typedef int qemudHandlerMonitorOutput(virConnectPtr conn,
|
typedef int qemudHandlerMonitorOutput(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
@ -722,7 +638,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
qemudLog(QEMUD_WARN, "Unable to write argv to logfile %d: %s",
|
qemudLog(QEMUD_WARN, "Unable to write argv to logfile %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
|
|
||||||
if (qemudExec(conn, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
|
if (virExecNonBlock(conn, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
|
||||||
vm->id = driver->nextvmid++;
|
vm->id = driver->nextvmid++;
|
||||||
vm->state = VIR_DOMAIN_RUNNING;
|
vm->state = VIR_DOMAIN_RUNNING;
|
||||||
|
|
||||||
@ -981,7 +897,7 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
|
|||||||
if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
|
if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = qemudExec(conn, argv, &network->dnsmasqPid, NULL, NULL);
|
ret = virExecNonBlock(conn, argv, &network->dnsmasqPid, NULL, NULL);
|
||||||
|
|
||||||
for (i = 0; argv[i]; i++)
|
for (i = 0; argv[i]; i++)
|
||||||
free(argv[i]);
|
free(argv[i]);
|
||||||
|
192
src/util.c
Normal file
192
src/util.c
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* utils.c: common, generic utility functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006, 2007 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
|
* Copyright (C) 2006, 2007 Binary Karma
|
||||||
|
* Copyright (C) 2006 Shuveb Hussain
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
* File created Jul 18, 2007 - Shuveb Hussain <shuveb@binarykarma.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <paths.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libvirt/virterror.h>
|
||||||
|
#include "event.h"
|
||||||
|
#include "buf.h"
|
||||||
|
|
||||||
|
#define MAX_ERROR_LEN 1024
|
||||||
|
|
||||||
|
static void
|
||||||
|
ReportError(virConnectPtr conn,
|
||||||
|
virDomainPtr dom,
|
||||||
|
virNetworkPtr net,
|
||||||
|
int code, const char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
char errorMessage[MAX_ERROR_LEN];
|
||||||
|
|
||||||
|
if (fmt) {
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(errorMessage, MAX_ERROR_LEN-1, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
} else {
|
||||||
|
errorMessage[0] = '\0';
|
||||||
|
}
|
||||||
|
__virRaiseError(conn, dom, net, VIR_FROM_NONE, code, VIR_ERR_ERROR,
|
||||||
|
NULL, NULL, NULL, -1, -1, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSetCloseExec(int fd) {
|
||||||
|
int flags;
|
||||||
|
if ((flags = fcntl(fd, F_GETFD)) < 0)
|
||||||
|
return -1;
|
||||||
|
flags |= FD_CLOEXEC;
|
||||||
|
if ((fcntl(fd, F_SETFD, flags)) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virSetNonBlock(int fd) {
|
||||||
|
int flags;
|
||||||
|
if ((flags = fcntl(fd, F_GETFL)) < 0)
|
||||||
|
return -1;
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
if ((fcntl(fd, F_SETFL, flags)) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_virExec(virConnectPtr conn,
|
||||||
|
char **argv,
|
||||||
|
int *retpid, int *outfd, int *errfd, int non_block) {
|
||||||
|
int pid, null;
|
||||||
|
int pipeout[2] = {-1,-1};
|
||||||
|
int pipeerr[2] = {-1,-1};
|
||||||
|
|
||||||
|
if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0) {
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot open %s : %s",
|
||||||
|
_PATH_DEVNULL, strerror(errno));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((outfd != NULL && pipe(pipeout) < 0) ||
|
||||||
|
(errfd != NULL && pipe(pipeerr) < 0)) {
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot create pipe : %s",
|
||||||
|
strerror(errno));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pid = fork()) < 0) {
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot fork child process : %s",
|
||||||
|
strerror(errno));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid) { /* parent */
|
||||||
|
close(null);
|
||||||
|
if (outfd) {
|
||||||
|
close(pipeout[1]);
|
||||||
|
if(non_block)
|
||||||
|
if(virSetNonBlock(pipeout[0]) == -1)
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Failed to set non-blocking file descriptor flag");
|
||||||
|
|
||||||
|
if(virSetCloseExec(pipeout[0]) == -1)
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Failed to set close-on-exec file descriptor flag");
|
||||||
|
*outfd = pipeout[0];
|
||||||
|
}
|
||||||
|
if (errfd) {
|
||||||
|
close(pipeerr[1]);
|
||||||
|
if(non_block)
|
||||||
|
if(virSetNonBlock(pipeerr[0]) == -1)
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Failed to set non-blocking file descriptor flag");
|
||||||
|
|
||||||
|
if(virSetCloseExec(pipeerr[0]) == -1)
|
||||||
|
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Failed to set close-on-exec file descriptor flag");
|
||||||
|
*errfd = pipeerr[0];
|
||||||
|
}
|
||||||
|
*retpid = pid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* child */
|
||||||
|
|
||||||
|
if (pipeout[0] > 0 && close(pipeout[0]) < 0)
|
||||||
|
_exit(1);
|
||||||
|
if (pipeerr[0] > 0 && close(pipeerr[0]) < 0)
|
||||||
|
_exit(1);
|
||||||
|
|
||||||
|
if (dup2(null, STDIN_FILENO) < 0)
|
||||||
|
_exit(1);
|
||||||
|
if (dup2(pipeout[1] > 0 ? pipeout[1] : null, STDOUT_FILENO) < 0)
|
||||||
|
_exit(1);
|
||||||
|
if (dup2(pipeerr[1] > 0 ? pipeerr[1] : null, STDERR_FILENO) < 0)
|
||||||
|
_exit(1);
|
||||||
|
|
||||||
|
close(null);
|
||||||
|
if (pipeout[1] > 0)
|
||||||
|
close(pipeout[1]);
|
||||||
|
if (pipeerr[1] > 0)
|
||||||
|
close(pipeerr[1]);
|
||||||
|
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
|
||||||
|
_exit(1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (pipeerr[0] > 0)
|
||||||
|
close(pipeerr[0]);
|
||||||
|
if (pipeerr[1] > 0)
|
||||||
|
close(pipeerr[1]);
|
||||||
|
if (pipeout[0] > 0)
|
||||||
|
close(pipeout[0]);
|
||||||
|
if (pipeout[1] > 0)
|
||||||
|
close(pipeout[1]);
|
||||||
|
if (null > 0)
|
||||||
|
close(null);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virExec(virConnectPtr conn,
|
||||||
|
char **argv,
|
||||||
|
int *retpid, int *outfd, int *errfd) {
|
||||||
|
|
||||||
|
_virExec(conn, argv, retpid, outfd, errfd, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virExecNonBlock(virConnectPtr conn,
|
||||||
|
char **argv,
|
||||||
|
int *retpid, int *outfd, int *errfd) {
|
||||||
|
|
||||||
|
_virExec(conn, argv, retpid, outfd, errfd, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
26
src/util.h
Normal file
26
src/util.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* utils.h: common, generic utility functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006, 2007 Binary Karma
|
||||||
|
* Copyright (C) 2006 Shuveb Hussain
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* File created Jul 18, 2007 - Shuveb Hussain <shuveb@binarykarma.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
int virExec(virConnectPtr conn, char **argv, int *retpid, int *outfd, int *errfd);
|
||||||
|
int virExecNonBlock(virConnectPtr conn, char **argv, int *retpid, int *outfd, int *errfd);
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user