Index: src/openvz_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_driver.c,v
retrieving revision 1.4
diff -u -r1.4 openvz_driver.c
--- src/openvz_driver.c	14 Aug 2007 01:23:59 -0000	1.4
+++ src/openvz_driver.c	23 Aug 2007 08:39:56 -0000
@@ -1,8 +1,10 @@
+
 /*
- * openvz_driver.c: core driver methods for managing OpenVZ VEs
+ * openvz_conf.c: config functions for managing OpenVZ VEs
  *
  * Copyright (C) 2006, 2007 Binary Karma
  * Copyright (C) 2006 Shuveb Hussain
+ * Copyright (C) 2007 Anoop Joe Cyriac
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,7 +20,10 @@
  * 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: Shuveb Hussain <shuveb@binarykarma.com>
+ * Authors: 
+ * Shuveb Hussain <shuveb@binarykarma.com>
+ * Anoop Joe Cyriac <anoop@binarykarma.com>
+ *
  */
 
 #ifdef WITH_OPENVZ
@@ -50,16 +55,13 @@
 
 #include <libvirt/virterror.h>
 
+#include "openvz_driver.h"
 #include "event.h"
 #include "buf.h"
 #include "util.h"
-#include "openvz_driver.h"
 #include "openvz_conf.h"
 #include "nodeinfo.h"
 
-
-#define openvzLog(level, msg...) fprintf(stderr, msg)
-
 static virDomainPtr openvzDomainLookupByID(virConnectPtr conn, int id);
 static char *openvzGetOSType(virDomainPtr dom);
 static int openvzGetNodeInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo);
@@ -84,6 +86,14 @@
 static int openvzCloseNetwork(virConnectPtr conn);
 static virDrvOpenStatus openvzOpenNetwork(virConnectPtr conn, const char *name ATTRIBUTE_UNUSED,
                                          int flags ATTRIBUTE_UNUSED);
+static virDomainPtr openvzDomainDefineXML(virConnectPtr conn,
+                                          const char *xml);
+static virDomainPtr openvzDomainCreateLinux(virConnectPtr conn,
+                                            const char *xml,
+                                            unsigned int flags
+                                            ATTRIBUTE_UNUSED);
+static int openvzDomainUndefine(virDomainPtr dom);
+
 struct openvz_driver ovz_driver;
 
 /* For errors internal to this library. */
@@ -122,7 +132,7 @@
 static char *openvzGetOSType(virDomainPtr dom)
 {
     /* OpenVZ runs on Linux and runs only Linux */
-    return strdup("Linux");
+    return strdup("linux");
 }
 
 
@@ -133,7 +143,7 @@
     virDomainPtr dom;
 
     if (!vm) {
-        error(conn, VIR_ERR_INTERNAL_ERROR, "no domain with matching uuid");
+        error(dom->conn, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
         return NULL;
     }
 
@@ -172,8 +182,9 @@
                        virDomainInfoPtr info) {
     struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData;
     struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid);
+
     if (!vm) {
-        error(dom->conn, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
+       error(dom->conn, VIR_ERR_INVALID_DOMAIN, "no domain with matching uuid");
         return -1;
     }
 
@@ -197,7 +208,7 @@
         error(dom->conn, VIR_ERR_INVALID_DOMAIN, "no domain with matching id");
         return -1;
     }
-    
+
     if (vm->status != VIR_DOMAIN_RUNNING) {
         error(dom->conn, VIR_ERR_OPERATION_DENIED, "domain is not in running state");
         return -1;
@@ -213,7 +224,7 @@
     vm->status = VIR_DOMAIN_SHUTOFF;
     ovz_driver.num_inactive ++;
     ovz_driver.num_active --;
-    
+
     return ret;
 }
 
@@ -227,7 +238,7 @@
         error(dom->conn, VIR_ERR_INVALID_DOMAIN, "no domain with matching id");
         return -1;
     }
-    
+
     if (vm->status != VIR_DOMAIN_RUNNING) {
         error(dom->conn, VIR_ERR_OPERATION_DENIED, "domain is not in running state");
         return -1;
@@ -239,22 +250,156 @@
         error(dom->conn, VIR_ERR_OPERATION_FAILED, "could not reboot domain");
         return -1;
     }
-    
+
     return ret;
 }
 
-static int openvzDomainCreate(virDomainPtr dom) {
+static virDomainPtr
+openvzDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+    struct openvz_driver *driver =
+        (struct openvz_driver *) conn->privateData;
+    struct openvz_vm_def *vmdef = NULL;
+    struct openvz_vm *vm = NULL;
+    virDomainPtr dom;
+    char cmdbuf[1060], cmdOption[1024];
+    int ret;
+
+    if (!(vmdef = openvzParseVMDef(conn, xml, NULL)))
+        return NULL;
+
+    vm = openvzFindVMByID(driver, strtoI(vmdef->name));
+    if (vm) {
+        openvzLog(OPENVZ_ERR,
+                  "Already an OPENVZ VM defined with the id '%d'",
+                  strtoI(vmdef->name));
+        return NULL;
+    }
+    if (!(vm = openvzAssignVMDef(conn, driver, vmdef))) {
+        openvzFreeVMDef(vmdef);
+        openvzLog(OPENVZ_ERR, "Error creating OPENVZ VM");
+        return NULL;
+    }
+
+    snprintf(cmdbuf, 1060, VZCTL " create %s", vmdef->name);
+    if ((vmdef->fs.tmpl && *(vmdef->fs.tmpl))) {
+        snprintf(cmdOption, 1024, " --ostemplate %s", vmdef->fs.tmpl);
+        strcat(cmdbuf, cmdOption);
+    }
+    if ((vmdef->profile && *(vmdef->profile))) {
+        snprintf(cmdOption, 1024, " --config %s", vmdef->profile);
+        strcat(cmdbuf, cmdOption);
+    }
+    if ((vmdef->net.ips->ip && *(vmdef->net.ips->ip))) {
+        snprintf(cmdOption, 1024, " --ipadd %s", vmdef->net.ips->ip);
+        strcat(cmdbuf, cmdOption);
+    }
+    if ((vmdef->net.hostname && *(vmdef->net.hostname))) {
+        snprintf(cmdOption, 1024, " --hostname %s", vmdef->net.hostname);
+        strcat(cmdbuf, cmdOption);
+    }
+
+    strcat(cmdbuf, " >/dev/null 2>&1");
+    ret = system(cmdbuf);
+
+    if (WEXITSTATUS(ret)) {
+        error(conn, VIR_ERR_OPERATION_FAILED, "could not start domain");
+        return -1;
+    }
+
+    dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
+    if (dom)
+        dom->id = vm->vpsid;
+    return dom;
+}
+
+static virDomainPtr
+openvzDomainCreateLinux(virConnectPtr conn, const char *xml,
+                        unsigned int flags ATTRIBUTE_UNUSED)
+{
+    struct openvz_vm_def *vmdef = NULL;
+    struct openvz_vm *vm = NULL;
+    virDomainPtr dom;
+    struct openvz_driver *driver =
+        (struct openvz_driver *) conn->privateData;
+    char cmdbuf[1060], cmdOption[1024];
+    int ret;
+
+    if (!(vmdef = openvzParseVMDef(conn, xml, NULL)))
+        return NULL;
+
+    vm = openvzFindVMByID(driver, strtoI(vmdef->name));
+    if (vm) {
+        openvzLog(OPENVZ_ERR,
+                  "Already an OPENVZ VM defined with the id '%d'",
+                  strtoI(vmdef->name));
+        return NULL;
+    }
+    if (!(vm = openvzAssignVMDef(conn, driver, vmdef))) {
+        openvzFreeVMDef(vmdef);
+        openvzLog(OPENVZ_ERR, "Error creating OPENVZ VM");
+        return NULL;
+    }
+
+    snprintf(cmdbuf, 1060, VZCTL " create %s", vmdef->name);
+    if ((vmdef->fs.tmpl && *(vmdef->fs.tmpl))) {
+        snprintf(cmdOption, 1024, " --ostemplate %s", vmdef->fs.tmpl);
+        strcat(cmdbuf, cmdOption);
+    }
+    if ((vmdef->profile && *(vmdef->profile))) {
+        snprintf(cmdOption, 1024, " --config %s", vmdef->profile);
+        strcat(cmdbuf, cmdOption);
+    }
+    if ((vmdef->net.ips->ip && *(vmdef->net.ips->ip))) {
+        snprintf(cmdOption, 1024, " --ipadd %s", vmdef->net.ips->ip);
+        strcat(cmdbuf, cmdOption);
+    }
+    if ((vmdef->net.hostname && *(vmdef->net.hostname))) {
+        snprintf(cmdOption, 1024, " --hostname %s", vmdef->net.hostname);
+        strcat(cmdbuf, cmdOption);
+    }
+
+    strcat(cmdbuf, " >/dev/null 2>&1");
+    ret = system(cmdbuf);
+
+    if (WEXITSTATUS(ret)) {
+        error(conn, VIR_ERR_OPERATION_FAILED, "could not define domain");
+        return NULL;
+    }
+
+    snprintf(cmdbuf, 1024, VZCTL " start %s >/dev/null 2>&1", vmdef->name);
+    ret = system(cmdbuf);
+    if (WEXITSTATUS(ret)) {
+        error(dom->conn, VIR_ERR_OPERATION_FAILED,
+              "could not start domain");
+        return NULL;
+    }
+    sscanf(vmdef->name, "%d", &vm->vpsid);
+    vm->status = VIR_DOMAIN_RUNNING;
+    ovz_driver.num_inactive--;
+    ovz_driver.num_active++;
+
+    dom = virGetDomain(conn, vm->vmdef->name, vm->vmdef->uuid);
+    if (dom)
+        dom->id = vm->vpsid;
+    return dom;
+
+}
+
+static int
+openvzDomainCreate(virDomainPtr dom)
+{
     char cmdbuf[1024];
     int ret;
     struct openvz_driver *driver = (struct openvz_driver *)dom->conn->privateData;
-    struct openvz_vm *vm = openvzFindVMByID(driver, dom->id);
+    struct openvz_vm *vm = openvzFindVMByName(driver, dom->name);
     struct openvz_vm_def *vmdef;
 
     if (!vm) {
         error(dom->conn, VIR_ERR_INVALID_DOMAIN, "no domain with matching id");
         return -1;
     }
-    
+
     if (vm->status != VIR_DOMAIN_SHUTOFF) {
         error(dom->conn, VIR_ERR_OPERATION_DENIED, "domain is not in shutoff state");
         return -1;
@@ -275,6 +420,38 @@
     return ret;
 }
 
+static int
+openvzDomainUndefine(virDomainPtr dom)
+{
+    char cmdbuf[1024];
+    int ret;
+    struct openvz_driver *driver =
+        (struct openvz_driver *) dom->conn->privateData;
+    struct openvz_vm *vm = openvzFindVMByUUID(driver, dom->uuid);
+
+    if (!vm) {
+        error(dom->conn, VIR_ERR_INVALID_DOMAIN,
+              "no domain with matching uuid");
+        return -1;
+    }
+
+    if (openvzIsActiveVM(vm)) {
+        error(dom->conn, VIR_ERR_INTERNAL_ERROR,
+              "cannot delete active domain");
+        return -1;
+    }
+    snprintf(cmdbuf, 1024, VZCTL " destroy %s >/dev/null 2>&1",
+             vm->vmdef->name);
+    ret = system(cmdbuf);
+    if (WEXITSTATUS(ret)) {
+        error(dom->conn, VIR_ERR_OPERATION_FAILED,
+              "could not undefine domain");
+        return -1;
+    }
+    openvzRemoveInactiveVM(driver, vm);
+    return ret;
+}
+
 static virDrvOpenStatus openvzOpen(virConnectPtr conn,
                            const char *name,
                            int flags ATTRIBUTE_UNUSED) {
@@ -306,7 +483,6 @@
     
     struct openvz_driver *driver = (struct openvz_driver *)conn->privateData;
     struct openvz_vm *vm = driver->vms;
-    
 
     while(vm) {
         openvzFreeVMDef(vm->vmdef);
@@ -315,10 +491,11 @@
     vm = driver->vms;
     while (vm) {
         struct openvz_vm *prev = vm;
+
         vm = vm->next;
         free(prev);
     }
-    
+
     conn->privateData = NULL;
 
     return 0;
@@ -328,13 +505,11 @@
     return strdup("OpenVZ");
 }
 
-
 static int openvzGetNodeInfo(virConnectPtr conn,
                              virNodeInfoPtr nodeinfo) {
     return virNodeInfoPopulate(conn, nodeinfo);
 }
 
-
 static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
     int got = 0;
     int veid, pid, outfd, errfd;
@@ -370,7 +545,7 @@
     int veid, pid, outfd, errfd, ret;
     char vpsname[OPENVZ_NAME_MAX];
     char buf[32];
-    const char *cmd[] = {VZLIST, "-ovpsid", "-H", NULL};
+    const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL};
 
     /* the -S options lists only stopped domains */
     ret = virExec(conn, (char **)cmd, &pid, -1, &outfd, &errfd);
@@ -391,14 +566,13 @@
     return got;
 }
 
-
 static int openvzNumDefinedDomains(virConnectPtr conn) {
     return ovz_driver.num_inactive; 
 }
 
 static int openvzStartup(void) {
     openvzAssignUUIDs();
-    
+
     return 0;
 }
 
@@ -427,13 +601,13 @@
     return VIR_DRV_OPEN_SUCCESS;
 }
 
-
 static virDriver openvzDriver = {
     VIR_DRV_OPENVZ,
     "OPENVZ",
     LIBVIR_VERSION_NUMBER,
     openvzOpen, /* open */
     openvzClose, /* close */
+    NULL, /* supports_feature */
     openvzGetType, /* type */
     NULL, /* version */
     NULL, /* hostname */
@@ -443,7 +617,7 @@
     NULL, /* getCapabilities */
     openvzListDomains, /* listDomains */
     openvzNumDomains, /* numOfDomains */
-    NULL, /* domainCreateLinux */
+    openvzDomainCreateLinux, /* domainCreateLinux */
     openvzDomainLookupByID, /* domainLookupByID */
     openvzDomainLookupByUUID, /* domainLookupByUUID */
     openvzDomainLookupByName, /* domainLookupByName */
@@ -468,8 +642,8 @@
     openvzListDefinedDomains, /* listDomains */
     openvzNumDefinedDomains, /* numOfDomains */
     openvzDomainCreate, /* domainCreate */
-    NULL, /* domainDefineXML */
-    NULL, /* domainUndefine */
+    openvzDomainDefineXML, /* domainDefineXML */
+    openvzDomainUndefine, /* domainUndefine */
     NULL, /* domainAttachDevice */
     NULL, /* domainDetachDevice */
     NULL, /* domainGetAutostart */
@@ -480,6 +654,7 @@
 };
 
 static virNetworkDriver openvzNetworkDriver = {
+    NULL, /* name */	
     openvzOpenNetwork, /* open */
     openvzCloseNetwork, /* close */
     NULL, /* numOfNetworks */
