[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH] Implement autostart commands for xen



Cole Robinson wrote:
> The attached patch implements the domain autostart commands for
> xen. The xen sexpr (since at least 3.0.4 = 1.5 years) has a 
> on_xend_start field which can be used to autostart a domain.
> 

Updated patch with fixes Dan recommended.

Thanks,
Cole

diff --git a/src/xen_unified.c b/src/xen_unified.c
index 91502dc..cf0a68d 100644
--- a/src/xen_unified.c
+++ b/src/xen_unified.c
@@ -1128,6 +1128,34 @@ xenUnifiedDomainDetachDevice (virDomainPtr dom, const char *xml)
     return -1;
 }
 
+static int
+xenUnifiedDomainGetAutostart (virDomainPtr dom, int *autostart)
+{
+    GET_PRIVATE(dom->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] && drivers[i]->domainGetAutostart &&
+            drivers[i]->domainGetAutostart (dom, autostart) == 0)
+            return 0;
+
+    return -1;
+}
+
+static int
+xenUnifiedDomainSetAutostart (virDomainPtr dom, int autostart)
+{
+    GET_PRIVATE(dom->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] && drivers[i]->domainSetAutostart &&
+            drivers[i]->domainSetAutostart (dom, autostart) == 0)
+            return 0;
+
+    return -1;
+}
+
 static char *
 xenUnifiedDomainGetSchedulerType (virDomainPtr dom, int *nparams)
 {
@@ -1291,6 +1319,8 @@ static virDriver xenUnifiedDriver = {
     .domainUndefine 		= xenUnifiedDomainUndefine,
     .domainAttachDevice 		= xenUnifiedDomainAttachDevice,
     .domainDetachDevice 		= xenUnifiedDomainDetachDevice,
+    .domainGetAutostart             = xenUnifiedDomainGetAutostart,
+    .domainSetAutostart             = xenUnifiedDomainSetAutostart,
     .domainGetSchedulerType	= xenUnifiedDomainGetSchedulerType,
     .domainGetSchedulerParameters	= xenUnifiedDomainGetSchedulerParameters,
     .domainSetSchedulerParameters	= xenUnifiedDomainSetSchedulerParameters,
diff --git a/src/xend_internal.c b/src/xend_internal.c
index 6d64509..90d3f4f 100644
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -115,8 +115,8 @@ struct xenUnifiedDriver xenDaemonDriver = {
     xenDaemonDomainUndefine, /* domainUndefine */
     xenDaemonAttachDevice, /* domainAttachDevice */
     xenDaemonDetachDevice, /* domainDetachDevice */
-    NULL, /* domainGetAutostart */
-    NULL, /* domainSetAutostart */
+    xenDaemonDomainGetAutostart, /* domainGetAutostart */
+    xenDaemonDomainSetAutostart, /* domainSetAutostart */
     xenDaemonGetSchedulerType, /* domainGetSchedulerType */
     xenDaemonGetSchedulerParameters, /* domainGetSchedulerParameters */
     xenDaemonSetSchedulerParameters, /* domainSetSchedulerParameters */
@@ -3728,6 +3728,115 @@ xenDaemonDetachDevice(virDomainPtr domain, const char *xml)
         "type", class, "dev", ref, "force", "0", "rm_cfg", "1", NULL));
 }
 
+int
+xenDaemonDomainGetAutostart(virDomainPtr domain,
+                            int *autostart)
+{
+    struct sexpr *root;
+    const char *tmp;
+    xenUnifiedPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
+        virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
+                     __FUNCTION__);
+        return (-1);
+    }
+
+    /* xm_internal.c (the support for defined domains from /etc/xen
+     * config files used by old Xen) will handle this.
+     */
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->xendConfigVersion < 3)
+        return(-1);
+
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+    if (root == NULL) {
+        virXendError (domain->conn, VIR_ERR_XEN_CALL,
+                      _("xenDaemonGetAutostart failed to find this domain"));
+        return (-1);
+    }
+
+    *autostart = 0;
+
+    tmp = sexpr_node(root, "domain/on_xend_start");
+    if (tmp && STREQ(tmp, "start")) {
+        *autostart = 1;
+    }
+
+    sexpr_free(root);
+    return 0;
+}
+
+int
+xenDaemonDomainSetAutostart(virDomainPtr domain,
+                            int autostart)
+{
+    struct sexpr *root, *autonode;
+    const char *autostr;
+    char buf[4096];
+    int ret = -1;
+    xenUnifiedPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
+        virXendError((domain ? domain->conn : NULL), VIR_ERR_INTERNAL_ERROR,
+                     __FUNCTION__);
+        return (-1);
+    }
+
+    /* xm_internal.c (the support for defined domains from /etc/xen
+     * config files used by old Xen) will handle this.
+     */
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->xendConfigVersion < 3)
+        return(-1);
+
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+    if (root == NULL) {
+        virXendError (domain->conn, VIR_ERR_XEN_CALL,
+                      _("xenDaemonSetAutostart failed to find this domain"));
+        return (-1);
+    }
+
+    autostr = sexpr_node(root, "domain/on_xend_start");
+    if (autostr) {
+        if (!STREQ(autostr, "ignore") && !STREQ(autostr, "start")) {
+            virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                         _("unexpected value from on_xend_start"));
+            goto error;
+        }
+
+        // Change the autostart value in place, then define the new sexpr
+        autonode = sexpr_lookup(root, "domain/on_xend_start");
+        free(autonode->u.s.car->u.value);
+        autonode->u.s.car->u.value = (autostart ? strdup("start")
+                                                : strdup("ignore"));
+        if (!(autonode->u.s.car->u.value)) {
+            virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                         _("no memory"));
+            goto error;
+        }
+
+        if (sexpr2string(root, buf, sizeof(buf)) == 0) {
+            virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                         _("sexpr2string failed"));
+            goto error;
+        }
+        if (xend_op(domain->conn, "", "op", "new", "config", buf, NULL) != 0) {
+            virXendError(domain->conn, VIR_ERR_XEN_CALL,
+                         _("Failed to redefine sexpr"));
+            goto error;
+        }
+    } else {
+        virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
+                     _("on_xend_start not present in sexpr"));
+        goto error;
+    }
+
+    ret = 0;
+  error:
+    sexpr_free(root);
+    return ret;
+}
 
 int
 xenDaemonDomainMigratePrepare (virConnectPtr dconn,
diff --git a/src/xend_internal.h b/src/xend_internal.h
index 80ef4f6..97f98f2 100644
--- a/src/xend_internal.h
+++ b/src/xend_internal.h
@@ -229,6 +229,10 @@ int	xenDaemonDomainGetVcpus		(virDomainPtr domain,
                                          int maxinfo,
                                          unsigned char *cpumaps,
                                          int maplen);
+int xenDaemonDomainGetAutostart          (virDomainPtr dom,
+                                          int *autostart);
+int xenDaemonDomainSetAutostart          (virDomainPtr domain,
+                                          int autostart);
 
 /* xen_unified calls through here. */
 extern struct xenUnifiedDriver xenDaemonDriver;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]