コード例 #1
0
ファイル: domain_event.c プロジェクト: hw-claudio/libvirt
/**
 * virDomainEventCallbackListRemoveID:
 * @conn: pointer to the connection
 * @cbList: the list
 * @callback: the callback to remove
 *
 * Internal function to remove a callback from a virDomainEventCallbackListPtr
 */
int
virDomainEventCallbackListRemoveID(virConnectPtr conn,
                                   virDomainEventCallbackListPtr cbList,
                                   int callbackID)
{
    int i;
    for (i = 0 ; i < cbList->count ; i++) {
        if (cbList->callbacks[i]->callbackID == callbackID &&
            cbList->callbacks[i]->conn == conn) {
            virFreeCallback freecb = cbList->callbacks[i]->freecb;
            if (freecb)
                (*freecb)(cbList->callbacks[i]->opaque);
            virUnrefConnect(cbList->callbacks[i]->conn);
            VIR_FREE(cbList->callbacks[i]);

            if (i < (cbList->count - 1))
                memmove(cbList->callbacks + i,
                        cbList->callbacks + i + 1,
                        sizeof(*(cbList->callbacks)) *
                                (cbList->count - (i + 1)));

            if (VIR_REALLOC_N(cbList->callbacks,
                              cbList->count - 1) < 0) {
                ; /* Failure to reduce memory allocation isn't fatal */
            }
            cbList->count--;

            return 0;
        }
    }

    eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("could not find event callback for removal"));
    return -1;
}
コード例 #2
0
ファイル: domain_event.c プロジェクト: hw-claudio/libvirt
/**
 * virDomainEventQueuePop:
 * @evtQueue: the queue of events
 *
 * Internal function to pop off, and return the front of the queue
 * NOTE: The caller is responsible for freeing the returned object
 *
 * Returns: virDomainEventPtr on success NULL on failure.
 */
virDomainEventPtr
virDomainEventQueuePop(virDomainEventQueuePtr evtQueue)
{
    virDomainEventPtr ret;

    if (!evtQueue || evtQueue->count == 0 ) {
        eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                         _("event queue is empty, nothing to pop"));
        return NULL;
    }

    ret = evtQueue->events[0];

    memmove(evtQueue->events,
            evtQueue->events + 1,
            sizeof(*(evtQueue->events)) *
                    (evtQueue->count - 1));

    if (VIR_REALLOC_N(evtQueue->events,
                        evtQueue->count - 1) < 0) {
        ; /* Failure to reduce memory allocation isn't fatal */
    }
    evtQueue->count--;

    return ret;
}
コード例 #3
0
ファイル: domain_event.c プロジェクト: hw-claudio/libvirt
int virDomainEventCallbackListMarkDeleteID(virConnectPtr conn,
                                           virDomainEventCallbackListPtr cbList,
                                           int callbackID)
{
    int i;
    for (i = 0 ; i < cbList->count ; i++) {
        if (cbList->callbacks[i]->callbackID == callbackID &&
            cbList->callbacks[i]->conn == conn) {
            cbList->callbacks[i]->deleted = 1;
            return 0;
        }
    }

    eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("could not find event callback for deletion"));
    return -1;
}
コード例 #4
0
ファイル: domain_event.c プロジェクト: hw-claudio/libvirt
int virDomainEventCallbackListMarkDelete(virConnectPtr conn,
                                         virDomainEventCallbackListPtr cbList,
                                         virConnectDomainEventCallback callback)
{
    int i;
    for (i = 0 ; i < cbList->count ; i++) {
        if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
            cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
            cbList->callbacks[i]->conn == conn) {
            cbList->callbacks[i]->deleted = 1;
            return 0;
        }
    }

    eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("could not find event callback for deletion"));
    return -1;
}
コード例 #5
0
ファイル: domain_event.c プロジェクト: hw-claudio/libvirt
/**
 * virDomainEventStateNew:
 * @timeout_cb: virEventTimeoutCallback to call when timer expires
 * @timeout_opaque: Data for timeout_cb
 * @timeout_free: Optional virFreeCallback for freeing timeout_opaque
 * @requireTimer: If true, return an error if registering the timer fails.
 *                This is fatal for drivers that sit behind the daemon
 *                (qemu, lxc), since there should always be a event impl
 *                registered.
 */
virDomainEventStatePtr
virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
                       void *timeout_opaque,
                       virFreeCallback timeout_free,
                       bool requireTimer)
{
    virDomainEventStatePtr state = NULL;

    if (VIR_ALLOC(state) < 0) {
        virReportOOMError();
        goto error;
    }

    if (VIR_ALLOC(state->callbacks) < 0) {
        virReportOOMError();
        goto error;
    }

    if (!(state->queue = virDomainEventQueueNew())) {
        goto error;
    }

    if ((state->timer = virEventAddTimeout(-1,
                                           timeout_cb,
                                           timeout_opaque,
                                           timeout_free)) < 0) {
        if (requireTimer == false) {
            VIR_DEBUG("virEventAddTimeout failed: No addTimeoutImpl defined. "
                      "continuing without events.");
        } else {
            eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                             _("could not initialize domain event timer"));
            goto error;
        }
    }

    return state;

error:
    virDomainEventStateFree(state);
    return NULL;
}
コード例 #6
0
ファイル: domain_event.c プロジェクト: intgr/libvirt
/**
 * virDomainEventCallbackListRemove:
 * @conn: pointer to the connection
 * @cbList: the list
 * @callback: the callback to remove
 *
 * Internal function to remove a callback from a virDomainEventCallbackListPtr
 */
static int
virDomainEventCallbackListRemove(virConnectPtr conn,
                                 virDomainEventCallbackListPtr cbList,
                                 virConnectDomainEventCallback callback)
{
    int ret = 0;
    int i;
    for (i = 0 ; i < cbList->count ; i++) {
        if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
            cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
            cbList->callbacks[i]->conn == conn) {
            virFreeCallback freecb = cbList->callbacks[i]->freecb;
            if (freecb)
                (*freecb)(cbList->callbacks[i]->opaque);
            virUnrefConnect(cbList->callbacks[i]->conn);
            VIR_FREE(cbList->callbacks[i]);

            if (i < (cbList->count - 1))
                memmove(cbList->callbacks + i,
                        cbList->callbacks + i + 1,
                        sizeof(*(cbList->callbacks)) *
                                (cbList->count - (i + 1)));

            if (VIR_REALLOC_N(cbList->callbacks,
                              cbList->count - 1) < 0) {
                ; /* Failure to reduce memory allocation isn't fatal */
            }
            cbList->count--;

            for (i = 0 ; i < cbList->count ; i++) {
                if (!cbList->callbacks[i]->deleted)
                    ret++;
            }
            return ret;
        }
    }

    eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("could not find event callback for removal"));
    return -1;
}
コード例 #7
0
ファイル: domain_event.c プロジェクト: hw-claudio/libvirt
/**
 * virDomainEventCallbackListAddID:
 * @conn: pointer to the connection
 * @cbList: the list
 * @eventID: the event ID
 * @callback: the callback to add
 * @opaque: opaque data tio pass to callback
 *
 * Internal function to add a callback from a virDomainEventCallbackListPtr
 */
int
virDomainEventCallbackListAddID(virConnectPtr conn,
                                virDomainEventCallbackListPtr cbList,
                                virDomainPtr dom,
                                int eventID,
                                virConnectDomainEventGenericCallback callback,
                                void *opaque,
                                virFreeCallback freecb)
{
    virDomainEventCallbackPtr event;
    int i;

    /* Check incoming */
    if ( !cbList ) {
        return -1;
    }

    /* check if we already have this callback on our list */
    for (i = 0 ; i < cbList->count ; i++) {
        if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
            cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
            cbList->callbacks[i]->conn == conn) {
            eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                             _("event callback already tracked"));
            return -1;
        }
    }
    /* Allocate new event */
    if (VIR_ALLOC(event) < 0)
        goto no_memory;
    event->conn = conn;
    event->cb = callback;
    event->eventID = eventID;
    event->opaque = opaque;
    event->freecb = freecb;

    if (dom) {
        if (VIR_ALLOC(event->dom) < 0)
            goto no_memory;
        if (!(event->dom->name = strdup(dom->name)))
            goto no_memory;
        memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
        event->dom->id = dom->id;
    }

    /* Make space on list */
    if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0)
        goto no_memory;

    event->conn->refs++;

    cbList->callbacks[cbList->count] = event;
    cbList->count++;

    event->callbackID = cbList->nextID++;

    return event->callbackID;

no_memory:
    virReportOOMError();

    if (event) {
        if (event->dom)
            VIR_FREE(event->dom->name);
        VIR_FREE(event->dom);
    }
    VIR_FREE(event);
    return -1;
}