From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 1 Dec 2006 22:13:58 -0000 Subject: [Cluster-devel] cluster/fence/agents/xvm fence_xvmd.c Message-ID: <20061201221358.31494.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL50 Changes by: lhh at sourceware.org 2006-12-01 22:13:57 Modified files: fence/agents/xvm: fence_xvmd.c Log message: Handle 0.1.9 case of libvirt returning a virDomainPtr + state for a VM that doesn't exist (vm state == VIR_DOMAIN_SHUTOFF) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/fence/agents/xvm/fence_xvmd.c.diff?cvsroot=cluster&only_with_tag=RHEL50&r1=1.4.4.1&r2=1.4.4.2 --- cluster/fence/agents/xvm/fence_xvmd.c 2006/11/13 16:14:18 1.4.4.1 +++ cluster/fence/agents/xvm/fence_xvmd.c 2006/12/01 22:13:57 1.4.4.2 @@ -207,6 +207,54 @@ } +static inline int +wait_domain(fence_req_t *req, virConnectPtr vp, int timeout) +{ + int tries = 0; + int response = 1; + virDomainPtr vdp; + virDomainInfo di; + + if (!(vdp = get_domain(req, vp))) + return 0; + + /* Check domain liveliness. If the domain is still here, + we return failure, and the client must then retry */ + /* XXX On the xen 3.0.4 API, we will be able to guarantee + synchronous virDomainDestroy, so this check will not + be necessary */ + do { + sleep(1); + vdp = get_domain(req, vp); + if (!vdp) { + dprintf(2, "Domain no longer exists\n"); + response = 0; + break; + } + + memset(&di, 0, sizeof(di)); + virDomainGetInfo(vdp, &di); + virDomainFree(vdp); + + if (di.state == VIR_DOMAIN_SHUTOFF) { + dprintf(2, "Domain has been shut off\n"); + response = 0; + break; + } + + dprintf(4, "Domain still exists (state %d) after %d seconds\n", + di.state, tries); + + if (++tries >= timeout) + break; + } while (1); + + return response; +} + + + + int do_fence_request_tcp(fence_req_t *req, fence_auth_type_t auth, void *key, size_t key_len, virConnectPtr vp) @@ -235,24 +283,18 @@ break; case FENCE_OFF: printf("Destroying domain %s...\n", (char *)req->domain); + + dprintf(2, "[OFF] Calling virDomainDestroy\n"); ret = virDomainDestroy(vdp); if (ret < 0) { - /* raise_error(vp); */ + printf("virDomainDestroy() failed: %d\n", ret); break; - } else { - sleep(1); } - /* Check domain liveliness. If the domain is still here, - we return failure, and the client must then retry */ - /* XXX On the xen 3.0.4 API, we will be able to guarantee - synchronous virDomainDestroy, so this check will not - be necessary */ - vdp = get_domain(req, vp); - if (!vdp) { - response = 0; /* Success! */ - } else { - virDomainFree(vdp); + response = wait_domain(req, vp, 15); + + if (response) { + printf("Domain still exists; fencing failed\n"); } break; case FENCE_REBOOT: @@ -271,42 +313,26 @@ "libvirt\n"); } - dprintf(2, "Calling virDomainDestroy\n"); + dprintf(2, "[REBOOT] Calling virDomainDestroy\n"); ret = virDomainDestroy(vdp); if (ret < 0) { printf("virDomainDestroy() failed: %d\n", ret); if (domain_desc) free(domain_desc); break; - } else { - /* Give it time for the operation to complete */ - sleep(3); } - /* Check domain liveliness. If the domain is still here, - we return failure, and the client must then retry */ - /* XXX On the xen 3.0.4 API, we will be able to guarantee - synchronous virDomainDestroy, so this check will not - be necessary */ - vdp = get_domain(req, vp); - if (!vdp) { - dprintf(2, "Domain no longer exists\n"); - response = 0; /* Success! */ - } else { - printf("Domain still exists; fencing failed\n"); - virDomainFree(vdp); - ret = 1; /* Failed to kill it */ - } + response = wait_domain(req, vp, 15); - /* Recreate the domain if possible */ - if (ret == 0 && domain_desc) { + if (response) { + printf("Domain still exists; fencing failed\n"); + } else if (domain_desc) { + /* Recreate the domain if possible */ /* Success */ dprintf(2, "Calling virDomainCreateLinux()...\n"); virDomainCreateLinux(vp, domain_desc, 0); - } - - if (domain_desc) free(domain_desc); + } break; } @@ -646,17 +672,14 @@ int mc_sock; char key[4096]; int key_len = 0; - char *my_options = "dfi:a:p:C:c:k:u?hVX"; + char *my_options = "dfi:a:p:C:c:k:u?hV"; void *h; args_init(&args); args_get_getopt(argc, argv, my_options, &args); - if (!(args.flags & F_NOCCS)) { - args_get_ccs(my_options, &args); - } args_finalize(&args); if (args.debug > 0) { - dset(args.debug); + _debug = args.debug; args_print(&args); }