qemu/block.c
/*
 * Reopen multiple BlockDriverStates atomically & transactionally.
 *
 * The queue passed in (bs_queue) must have been built up previous
 * via bdrv_reopen_queue().
 *
 * Reopens all BDS specified in the queue, with the appropriate
 * flags.  All devices are prepared for reopen, and failure of any
 * device will cause all device changes to be abandoned, and intermediate
 * data cleaned up.
 *
 * If all devices prepare successfully, then the changes are committed
 * to all devices.
 *
 * All affected nodes must be drained between bdrv_reopen_queue() and
 * bdrv_reopen_multiple().
 */
Reopen multiple BlockDriverStates atomically & transactionally.
The queue passed in (bs_queue) must have been built up previous
via bdrv_reopen_queue().

Reopens all BDS specified in the queue, with the appropriate
flags.  All devices are prepared for reopen, and failure of any
device will cause all device changes to be abandoned, and intermediate
data cleaned up.

If all devices prepare successfully, then the changes are committed
to all devices.

All affected nodes must be drained between bdrv_reopen_queue() and
bdrv_reopen_multiple().
Reopen multiple BlockDriverStates atomically & transactionally . The queue passed in ( bs_queue ) must have been built up previous via bdrv_reopen_queue () . Reopens all BDS specified in the queue with the appropriate flags . All devices are prepared for reopen and failure of any device will cause all device changes to be abandoned and intermediate data cleaned up . If all devices prepare successfully then the changes are committed to all devices . All affected nodes must be drained between bdrv_reopen_queue () and bdrv_reopen_multiple () .
int bdrv_reopen_multiple(AioContext *ctx, BlockReopenQueue *bs_queue, Error **errp)
{
    int ret = -1;
    BlockReopenQueueEntry *bs_entry, *next;
    Error *local_err = NULL;
    assert(bs_queue != NULL);
    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
        assert(bs_entry->state.bs->quiesce_counter > 0);
        if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, &local_err)) {
            error_propagate(errp, local_err);
            goto cleanup;
        }
        bs_entry->prepared = true;
    }
    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
        bdrv_reopen_commit(&bs_entry->state);
    }
    ret = 0;
cleanup:
    QSIMPLEQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
        if (ret) {
            if (bs_entry->prepared) {
                bdrv_reopen_abort(&bs_entry->state);
            }
            qobject_unref(bs_entry->state.explicit_options);
            qobject_unref(bs_entry->state.options);
        }
        g_free(bs_entry);
    }
    g_free(bs_queue);
    return ret;
}
int bdrv_reopen_multiple ( AioContext * ctx , BlockReopenQueue * bs_queue , Error * * errp ) { int ret = -1 ; BlockReopenQueueEntry * bs_entry , * next ; Error * local_err = NULL ; assert ( bs_queue != NULL ) ; QSIMPLEQ_FOREACH ( bs_entry , bs_queue , entry ) { assert ( bs_entry -> state . bs -> quiesce_counter > 0 ) ; if ( bdrv_reopen_prepare ( & bs_entry -> state , bs_queue , & local_err ) ) { error_propagate ( errp , local_err ) ; goto cleanup ; } bs_entry -> prepared = true ; } QSIMPLEQ_FOREACH ( bs_entry , bs_queue , entry ) { bdrv_reopen_commit ( & bs_entry -> state ) ; } ret = 0 ; cleanup : QSIMPLEQ_FOREACH_SAFE ( bs_entry , bs_queue , entry , next ) { if ( ret ) { if ( bs_entry -> prepared ) { bdrv_reopen_abort ( & bs_entry -> state ) ; } qobject_unref ( bs_entry -> state . explicit_options ) ; qobject_unref ( bs_entry -> state . options ) ; } g_free ( bs_entry ) ; } g_free ( bs_queue ) ; return ret ; }
Reopen multiple BlockDriverStates atomically & transactionally.
Reopen multiple BlockDriverStates atomically & transactionally .
/* If we reach this point, we have success and just need to apply the
     * changes
     */