blockdev.c (edd5adeecddf665e7954bc146ff458bb30f178ae) | blockdev.c (a36e458cdda0196911c1cbe7cfe6f9530f2280e3) |
---|---|
1/* 2 * QEMU host block devices 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or 7 * later. See the COPYING file in the top-level directory. 8 * --- 1440 unchanged lines hidden (view full) --- 1449 TransactionProperties *txn_props; 1450 QSIMPLEQ_ENTRY(BlkActionState) entry; 1451}; 1452 1453/* internal snapshot private data */ 1454typedef struct InternalSnapshotState { 1455 BlkActionState common; 1456 BlockDriverState *bs; | 1/* 2 * QEMU host block devices 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or 7 * later. See the COPYING file in the top-level directory. 8 * --- 1440 unchanged lines hidden (view full) --- 1449 TransactionProperties *txn_props; 1450 QSIMPLEQ_ENTRY(BlkActionState) entry; 1451}; 1452 1453/* internal snapshot private data */ 1454typedef struct InternalSnapshotState { 1455 BlkActionState common; 1456 BlockDriverState *bs; |
1457 AioContext *aio_context; | |
1458 QEMUSnapshotInfo sn; 1459 bool created; 1460} InternalSnapshotState; 1461 1462 1463static int action_check_completion_mode(BlkActionState *s, Error **errp) 1464{ 1465 if (s->txn_props->completion_mode != ACTION_COMPLETION_MODE_INDIVIDUAL) { --- 14 unchanged lines hidden (view full) --- 1480 const char *device; 1481 const char *name; 1482 BlockDriverState *bs; 1483 QEMUSnapshotInfo old_sn, *sn; 1484 bool ret; 1485 qemu_timeval tv; 1486 BlockdevSnapshotInternal *internal; 1487 InternalSnapshotState *state; | 1457 QEMUSnapshotInfo sn; 1458 bool created; 1459} InternalSnapshotState; 1460 1461 1462static int action_check_completion_mode(BlkActionState *s, Error **errp) 1463{ 1464 if (s->txn_props->completion_mode != ACTION_COMPLETION_MODE_INDIVIDUAL) { --- 14 unchanged lines hidden (view full) --- 1479 const char *device; 1480 const char *name; 1481 BlockDriverState *bs; 1482 QEMUSnapshotInfo old_sn, *sn; 1483 bool ret; 1484 qemu_timeval tv; 1485 BlockdevSnapshotInternal *internal; 1486 InternalSnapshotState *state; |
1487 AioContext *aio_context; |
|
1488 int ret1; 1489 1490 g_assert(common->action->type == 1491 TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC); 1492 internal = common->action->u.blockdev_snapshot_internal_sync.data; 1493 state = DO_UPCAST(InternalSnapshotState, common, common); 1494 1495 /* 1. parse input */ --- 5 unchanged lines hidden (view full) --- 1501 return; 1502 } 1503 1504 bs = qmp_get_root_bs(device, errp); 1505 if (!bs) { 1506 return; 1507 } 1508 | 1488 int ret1; 1489 1490 g_assert(common->action->type == 1491 TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC); 1492 internal = common->action->u.blockdev_snapshot_internal_sync.data; 1493 state = DO_UPCAST(InternalSnapshotState, common, common); 1494 1495 /* 1. parse input */ --- 5 unchanged lines hidden (view full) --- 1501 return; 1502 } 1503 1504 bs = qmp_get_root_bs(device, errp); 1505 if (!bs) { 1506 return; 1507 } 1508 |
1509 /* AioContext is released in .clean() */ 1510 state->aio_context = bdrv_get_aio_context(bs); 1511 aio_context_acquire(state->aio_context); | 1509 aio_context = bdrv_get_aio_context(bs); 1510 aio_context_acquire(aio_context); |
1512 1513 state->bs = bs; | 1511 1512 state->bs = bs; |
1513 1514 /* Paired with .clean() */ |
|
1514 bdrv_drained_begin(bs); 1515 1516 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) { | 1515 bdrv_drained_begin(bs); 1516 1517 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) { |
1517 return; | 1518 goto out; |
1518 } 1519 1520 if (bdrv_is_read_only(bs)) { 1521 error_setg(errp, "Device '%s' is read only", device); | 1519 } 1520 1521 if (bdrv_is_read_only(bs)) { 1522 error_setg(errp, "Device '%s' is read only", device); |
1522 return; | 1523 goto out; |
1523 } 1524 1525 if (!bdrv_can_snapshot(bs)) { 1526 error_setg(errp, "Block format '%s' used by device '%s' " 1527 "does not support internal snapshots", 1528 bs->drv->format_name, device); | 1524 } 1525 1526 if (!bdrv_can_snapshot(bs)) { 1527 error_setg(errp, "Block format '%s' used by device '%s' " 1528 "does not support internal snapshots", 1529 bs->drv->format_name, device); |
1529 return; | 1530 goto out; |
1530 } 1531 1532 if (!strlen(name)) { 1533 error_setg(errp, "Name is empty"); | 1531 } 1532 1533 if (!strlen(name)) { 1534 error_setg(errp, "Name is empty"); |
1534 return; | 1535 goto out; |
1535 } 1536 1537 /* check whether a snapshot with name exist */ 1538 ret = bdrv_snapshot_find_by_id_and_name(bs, NULL, name, &old_sn, 1539 &local_err); 1540 if (local_err) { 1541 error_propagate(errp, local_err); | 1536 } 1537 1538 /* check whether a snapshot with name exist */ 1539 ret = bdrv_snapshot_find_by_id_and_name(bs, NULL, name, &old_sn, 1540 &local_err); 1541 if (local_err) { 1542 error_propagate(errp, local_err); |
1542 return; | 1543 goto out; |
1543 } else if (ret) { 1544 error_setg(errp, 1545 "Snapshot with name '%s' already exists on device '%s'", 1546 name, device); | 1544 } else if (ret) { 1545 error_setg(errp, 1546 "Snapshot with name '%s' already exists on device '%s'", 1547 name, device); |
1547 return; | 1548 goto out; |
1548 } 1549 1550 /* 3. take the snapshot */ 1551 sn = &state->sn; 1552 pstrcpy(sn->name, sizeof(sn->name), name); 1553 qemu_gettimeofday(&tv); 1554 sn->date_sec = tv.tv_sec; 1555 sn->date_nsec = tv.tv_usec * 1000; 1556 sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 1557 1558 ret1 = bdrv_snapshot_create(bs, sn); 1559 if (ret1 < 0) { 1560 error_setg_errno(errp, -ret1, 1561 "Failed to create snapshot '%s' on device '%s'", 1562 name, device); | 1549 } 1550 1551 /* 3. take the snapshot */ 1552 sn = &state->sn; 1553 pstrcpy(sn->name, sizeof(sn->name), name); 1554 qemu_gettimeofday(&tv); 1555 sn->date_sec = tv.tv_sec; 1556 sn->date_nsec = tv.tv_usec * 1000; 1557 sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 1558 1559 ret1 = bdrv_snapshot_create(bs, sn); 1560 if (ret1 < 0) { 1561 error_setg_errno(errp, -ret1, 1562 "Failed to create snapshot '%s' on device '%s'", 1563 name, device); |
1563 return; | 1564 goto out; |
1564 } 1565 1566 /* 4. succeed, mark a snapshot is created */ 1567 state->created = true; | 1565 } 1566 1567 /* 4. succeed, mark a snapshot is created */ 1568 state->created = true; |
1569 1570out: 1571 aio_context_release(aio_context); |
|
1568} 1569 1570static void internal_snapshot_abort(BlkActionState *common) 1571{ 1572 InternalSnapshotState *state = 1573 DO_UPCAST(InternalSnapshotState, common, common); 1574 BlockDriverState *bs = state->bs; 1575 QEMUSnapshotInfo *sn = &state->sn; | 1572} 1573 1574static void internal_snapshot_abort(BlkActionState *common) 1575{ 1576 InternalSnapshotState *state = 1577 DO_UPCAST(InternalSnapshotState, common, common); 1578 BlockDriverState *bs = state->bs; 1579 QEMUSnapshotInfo *sn = &state->sn; |
1580 AioContext *aio_context; |
|
1576 Error *local_error = NULL; 1577 1578 if (!state->created) { 1579 return; 1580 } 1581 | 1581 Error *local_error = NULL; 1582 1583 if (!state->created) { 1584 return; 1585 } 1586 |
1587 aio_context = bdrv_get_aio_context(state->bs); 1588 aio_context_acquire(aio_context); 1589 |
|
1582 if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) { 1583 error_reportf_err(local_error, 1584 "Failed to delete snapshot with id '%s' and " 1585 "name '%s' on device '%s' in abort: ", 1586 sn->id_str, sn->name, 1587 bdrv_get_device_name(bs)); 1588 } | 1590 if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) { 1591 error_reportf_err(local_error, 1592 "Failed to delete snapshot with id '%s' and " 1593 "name '%s' on device '%s' in abort: ", 1594 sn->id_str, sn->name, 1595 bdrv_get_device_name(bs)); 1596 } |
1597 1598 aio_context_release(aio_context); |
|
1589} 1590 1591static void internal_snapshot_clean(BlkActionState *common) 1592{ 1593 InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState, 1594 common, common); | 1599} 1600 1601static void internal_snapshot_clean(BlkActionState *common) 1602{ 1603 InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState, 1604 common, common); |
1605 AioContext *aio_context; |
|
1595 | 1606 |
1596 if (state->aio_context) { 1597 if (state->bs) { 1598 bdrv_drained_end(state->bs); 1599 } 1600 aio_context_release(state->aio_context); | 1607 if (!state->bs) { 1608 return; |
1601 } | 1609 } |
1610 1611 aio_context = bdrv_get_aio_context(state->bs); 1612 aio_context_acquire(aio_context); 1613 1614 bdrv_drained_end(state->bs); 1615 1616 aio_context_release(aio_context); |
|
1602} 1603 1604/* external snapshot private data */ 1605typedef struct ExternalSnapshotState { 1606 BlkActionState common; 1607 BlockDriverState *old_bs; 1608 BlockDriverState *new_bs; 1609 bool overlay_appended; --- 2594 unchanged lines hidden --- | 1617} 1618 1619/* external snapshot private data */ 1620typedef struct ExternalSnapshotState { 1621 BlkActionState common; 1622 BlockDriverState *old_bs; 1623 BlockDriverState *new_bs; 1624 bool overlay_appended; --- 2594 unchanged lines hidden --- |