revertSnapshot fails with an NPE when the snapshot's volume has been deleted

未關閉
#14,644 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@bhouse-nexthop 已經在處理了。

開始於 2026年11月9日。

  • #14646 來自 @bhouse-nexthop —— 未關閉

評估

難度
4/5
預估耗時
3-5 天
新手友好度
55/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
java

研究方向

Start by reading SnapshotManagerImpl.revertSnapshot and the snapshot copy path that chooses a source zone; the issue identifies findById() as the lookup that returns null for removed volumes. Then inspect VolumeApiServiceImpl.allocVolume and TemplateManagerImpl.createPrivateTemplate for snapshot based creation when the volume row is missing. Add clear errors for the missing volume cases and use the snapshot's recorded zone for copy; done when all four API paths handle these cases without an NPE.

由索引模型根據 Issue 內容生成。

描述

problem

revertSnapshot fails with a NullPointerException when the snapshot's volume has been deleted:

Cannot invoke "com.cloud.storage.VolumeVO.getState()" because "volume" is null
    at com.cloud.storage.snapshot.SnapshotManagerImpl.revertSnapshot

SnapshotManagerImpl.revertSnapshot looks the volume up with findById(), which does not return removed volumes, and uses the result without a null check. Volume snapshots outlive their volume, so any snapshot of a deleted volume hits this. The caller gets an internal error instead of being told why the snapshot cannot be reverted.

A few other snapshot APIs have the same gap:

  • copySnapshot without sourcezoneid takes the source zone from the volume, also looked up with findById(). For a snapshot of a deleted volume it fails with Cannot invoke "com.cloud.storage.Volume.getDataCenterId()" because "volume" is null. The copy itself does not need the volume, and the same copy works when sourcezoneid is passed.
  • createVolume from a snapshot and createTemplate from a snapshot look the volume up including removed rows, so a deleted volume is fine. They still NPE when the volume row itself is gone (parentVolume.getPassphraseId() in VolumeApiServiceImpl.allocVolume; for createTemplate, the template record is created and the job then fails in TemplateManagerImpl.createPrivateTemplate). A missing row is the case in #14599.
versions

4.22, and main.

The steps to reproduce the bug
  1. Create a data volume, attach it to a VM, and take a volume snapshot of it.
  2. Detach and delete the volume. The snapshot remains.
  3. Call revertSnapshot id=<snapshot>. It fails with the NPE above.
  4. Call copySnapshot id=<snapshot> destzoneids=<another zone> without sourcezoneid. It fails with the getDataCenterId() NPE.

For createVolume snapshotid= and createTemplate snapshotid=, the volume row has to be missing from the volumes table.

What to do about it?
  • revertSnapshot: refuse with a clear error when the snapshot's volume no longer exists.
  • copySnapshot: when the volume is gone, take the source zone from the snapshot, which records the zone it was taken in.
  • createVolume and createTemplate from a snapshot: refuse with a clear error when the volume row is missing, instead of failing with an NPE.
主要語言
Java
星號
3.1k
分支
1.4k
平均合併
7 天 16 小時
30 天內合併 PR
15

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

apache/cloudstack 的其他 Issue

查看 apache/cloudstack 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。