[libvirt-users] [Problem] C# virDomainShutdown

Matthias Bolte matthias.bolte at googlemail.com
Tue Jan 24 16:50:05 UTC 2012

2012/1/24 Danny Fonk <danny.fonk at gmx.de>:
> Hey there,
> im using libvirt since 2 weeks now and there are still some issues im confronted with. I use libvirt in C# and I'm running a 32-bit machine on Windows 7. Actually my worst problem is, is that I'm not able to Shutdown on machine no matter which command I'm using. virDomainShutdown isn't working nor virDomainDestroy. Basically I use the virConnectOpenAuth example to make a test on this. You'll find a code-excerpt in the attachment. Everything else is working. Like Domain.GetName etc. - i just can't figure out the failure and I wanted to ask if the mistake is in the API since it's not tested on a 32-bit Windows. Already thanks for the support.

You say virDomainShutdown and virDomainDestroy doesn't work from C#.
Did you test the commandline tool virsh with the shutdown and destroy
command to test whether the problem is in the C# bindings or libvirt

What hypervisor are you connecting to?

Also why do you think it's not tested on 32-bit Windows?

Oh and actually there is a problem in your attached code. I've added
some comments to your code showing the problem:

foreach (int runningDomainID in runningDomainIDs)
    IntPtr domainPtr = Domain.LookupByID(conn, runningDomainID);
    if (domainPtr == IntPtr.Zero)
        MessageBox.Show("Unable to lookup domains by id",
                        "Lookup domain failed",
        // NOTE: here you checked hat the domain lookup failed.
        // as the domain pointer is invalid you should not be using to
        // call Domain.GetName on it next. you should insert a
        // continue or break statement here
    string domainName = Domain.GetName(domainPtr);

    // NOTE: here you free the domain pointer. it is now invalid and
    // cannot be used anymore. you should remove this line here and
    // move it to the end of the foreach loop body.
    // in the virConnectOpenAuth example the free call is okay here,
    // because the example doesn't use the domain pointer afterwards
    // anymore

    if (string.IsNullOrEmpty(domainName))
    { ... }

    if (domainName == selectedString)
        // NOTE: here you're using the invalid domain pointer again.
        // this doesn't work and is probably the case that the destroy
        // call doesn't work.
        // libvirt has probably told you that you provided an invalid domain
        // pointer but you didn't look at the reported error or you weren't
        // aware of the error reporting facilities. have a look at the
        // virConnectSetErrorFunc example and the Errors.GetLastError
        // call
        int i = Domain.Destroy(domainPtr);
        if (i == -1)
        { ... }
        else if (i == 0)
        { ... }

        // NOTE: you also need to duplicate the Domain.Free call here,
        // otherwise you might leave the loop here and leak the domain
        // pointer here. unfortunately the C# bindings are not yet garbage
        // collector enabled and you need to free libvirt resources such as
        // domains and connections manually

    // NOTE: move the Domain.Free call here and it should work

Also why are you using the complicated loop to lookup a domain by
name? You could just have use DomainLookupByName instead.

Matthias Bolte

More information about the libvirt-users mailing list