예제 #1
0
static int
testDomainCreateXMLOld(const void *data)
{
    const objecteventTest *test = data;
    lifecycleEventCounter counter;
    virDomainPtr dom = NULL;
    int ret = -1;
    bool registered = false;

    lifecycleEventCounter_reset(&counter);

    if (virConnectDomainEventRegister(test->conn,
                                      domainLifecycleCb,
                                      &counter, NULL) != 0)
        goto cleanup;
    registered = true;
    dom = virDomainCreateXML(test->conn, domainDef, 0);

    if (dom == NULL || virEventRunDefaultImpl() < 0)
        goto cleanup;

    if (counter.startEvents != 1 || counter.unexpectedEvents > 0)
        goto cleanup;

    if (virConnectDomainEventDeregister(test->conn, domainLifecycleCb) != 0)
        goto cleanup;
    registered = false;
    ret = 0;

cleanup:
    if (registered)
        virConnectDomainEventDeregister(test->conn, domainLifecycleCb);
    if (dom) {
        virDomainDestroy(dom);
        virDomainFree(dom);
    }

    return ret;
}
예제 #2
0
static void *
event_thread(void *arg)
{
	struct event_args *args = (struct event_args *)arg;
	virConnectPtr dconn = NULL;
	int callback1ret = -1;
	int sts;

	dbg_printf(3, "Libvirt event listener starting\n");
	if (args->uri)
		dbg_printf(3," * URI: %s\n", args->uri);
	if (args->path)
		dbg_printf(3," * Socket path: %s\n", args->path);
	dbg_printf(3," * Mode: %s\n", args->mode ? "VMChannel" : "Serial");

top:
	virEventRegisterImpl(myEventAddHandleFunc,
			     myEventUpdateHandleFunc,
			     myEventRemoveHandleFunc,
			     myEventAddTimeoutFunc,
			     myEventUpdateTimeoutFunc,
			     myEventRemoveTimeoutFunc);

	dconn = virConnectOpen(args->uri);
	if (!dconn) {
		dbg_printf(1, "Error connecting to libvirt\n");
		goto out;
	}

	DEBUG0("Registering domain event cbs");

	registerExisting(dconn, args->path, args->mode);

	callback1ret =
	    virConnectDomainEventRegister(dconn, myDomainEventCallback1, arg, NULL);

	if (callback1ret == 0) {
		while (run) {
			struct pollfd pfd = {
				.fd = h_fd,
				.events = h_event,
				.revents = 0
			};

			sts = poll(&pfd, 1, TIMEOUT_MS);
			/* We are assuming timeout of 0 here - so execute every time */
			if (t_cb && t_active) {
				t_cb(t_timeout, t_opaque);
			}

			if (sts == 0) {
				/* DEBUG0("Poll timeout"); */
				continue;
			}

			if (sts < 0) {
				DEBUG0("Poll failed");
				continue;
			}

			if (pfd.revents & POLLHUP) {
				DEBUG0("Reset by peer");
				virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
				if (dconn && virConnectClose(dconn) < 0)
					dbg_printf(1, "error closing libvirt connection\n");
				DEBUG0("Attempting to reinitialize libvirt connection");
				goto top;
			}

			if (h_cb) {
				h_cb(0, h_fd,
				     myPollEventToEventHandleType(pfd.revents & h_event),
				     h_opaque);
			}
		}

		DEBUG0("Deregistering event handlers");
		virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
	}

	DEBUG0("Closing connection");
	if (dconn && virConnectClose(dconn) < 0) {
		dbg_printf(1, "error closing libvirt connection\n");
	}

out:
	free(args->uri);
	free(args->path);
	free(args);
	return NULL;
}


int
start_event_listener(const char *uri, const char *path, int mode, int *wake_fd)
{
	struct event_args *args = NULL;
	int wake_pipe[2];

	virInitialize();

	args = malloc(sizeof(*args));
	if (!args)
		return -1;
	memset(args, 0, sizeof(*args));
       
	if (pipe2(wake_pipe, O_CLOEXEC) < 0) {
		goto out_fail;
	}

	if (uri) {
	       args->uri = strdup(uri);
	       if (args->uri == NULL)
		       goto out_fail;
	}

	if (path) {
	       args->path = strdup(path);
	       if (args->path == NULL)
		       goto out_fail;
	}

	args->mode = mode;
	//args->p_tid = pthread_self();
	*wake_fd = wake_pipe[0];
	args->wake_fd = wake_pipe[1];

	run = 1;

	return pthread_create(&event_tid, NULL, event_thread, args);

out_fail:
	free(args->uri);
	free(args->path);
	free(args);
	return -1;
}


int
stop_event_listener(void)
{
	run = 0;
	//pthread_cancel(event_tid);
	pthread_join(event_tid, NULL);
	event_tid = 0;

	return 0;
}
예제 #3
0
static int
testDomainCreateXMLMixed(const void *data)
{
    const objecteventTest *test = data;
    lifecycleEventCounter counter;
    virDomainPtr dom;
    int ret = -1;
    int id1 = -1;
    int id2 = -1;
    bool registered = false;

    lifecycleEventCounter_reset(&counter);

    /* Fun with mixing old and new API, also with global and
     * per-domain.  Handler should be fired three times, once for each
     * registration.  */
    dom = virDomainDefineXML(test->conn, domainDef);
    if (dom == NULL)
        goto cleanup;

    id1 = virConnectDomainEventRegisterAny(test->conn, dom,
                                           VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                           VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
                                           &counter, NULL);
    if (id1 < 0)
        goto cleanup;
    if (virConnectDomainEventRegister(test->conn,
                                      domainLifecycleCb,
                                      &counter, NULL) != 0)
        goto cleanup;
    registered = true;
    id2 = virConnectDomainEventRegisterAny(test->conn, NULL,
                                           VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                           VIR_DOMAIN_EVENT_CALLBACK(&domainLifecycleCb),
                                           &counter, NULL);
    if (id2 < 0)
        goto cleanup;

    dom = virDomainCreateXML(test->conn, domainDef, 0);
    if (dom == NULL || virEventRunDefaultImpl() < 0)
        goto cleanup;

    if (counter.startEvents != 3 || counter.unexpectedEvents > 0)
        goto cleanup;

    if (virConnectDomainEventDeregister(test->conn, domainLifecycleCb) != 0)
        goto cleanup;
    registered = false;
    if (virConnectDomainEventDeregisterAny(test->conn, id1) != 0)
        goto cleanup;
    id1 = -1;
    if (virConnectDomainEventDeregisterAny(test->conn, id2) != 0)
        goto cleanup;
    id2 = -1;
    ret = 0;

cleanup:
    if (id1 >= 0)
        virConnectDomainEventDeregisterAny(test->conn, id1);
    if (id2 >= 0)
        virConnectDomainEventDeregisterAny(test->conn, id2);
    if (registered)
        virConnectDomainEventDeregister(test->conn, domainLifecycleCb);
    if (dom != NULL) {
        virDomainUndefine(dom);
        virDomainDestroy(dom);
        virDomainFree(dom);
    }

    return ret;
}