From 327cab4f667e9da978fa80c9387f6d05a26385a9 Mon Sep 17 00:00:00 2001 From: "yingzhe.hu" Date: Thu, 20 Aug 2026 11:55:42 +0800 Subject: [PATCH 1/3] [snapshot]: add conflict error mappings Keep snapshot execution lock-free and add the error mappings required by premium backup conflict checks. Resolves: ZSTAC-86666 Change-Id: Ib5d2ad686fa92394a771980c1d1425adea6ca02f --- conf/i18n/globalErrorCodeMapping/global-error-de-DE.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-en_US.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-id-ID.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-th-TH.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json | 3 +++ conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json | 3 +++ .../utils/clouderrorcode/CloudOperationsErrorCode.java | 6 ++++++ 11 files changed, 36 insertions(+) diff --git a/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json b/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json index b3602b32e16..f71777783bd 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "Kein primary storage [uuid:%s] existiert", "ORG_ZSTACK_V2V_10019": "primary storage mit UUID:%s wird für die virtuelle Maschinenmigration v2v nicht unterstützt", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "Fehler beim Übergang des Volume-Snapshots [uuid:%s, name:%s] aufgrund des Statusereignisses [%s]", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "Die %s-Aufgabe für die VM [UUID: %s] kann nicht aktiviert werden, während der Ketten-Snapshot [UUID: %s] geändert wird.", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "Fehler beim Abrufen der Größe von Volume [uuid:%s, installPath:%s] vom primary storage [uuid:%s], aufgrund von %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "Fehler beim Abrufen der Größe von Volume [uuid:%s, installPath:%s] vom primary storage [uuid:%s], %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm [uuid:%s] befindet sich nicht in einem Running-, Paused-, Destroyed- oder Stopped-Status; aktueller Status [%s]", @@ -2590,6 +2591,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "Backup-Speicher [UUID: %s] ist nicht mit der Cloud-Umgebung verbunden. Bitte stellen Sie sicher, dass er ordnungsgemäß konfiguriert und integriert ist.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s] ist keine Baremetal-Cluster-Konfiguration.", "ORG_ZSTACK_STORAGE_CDP_10042": "Die VM [UUID: %s] hat bereits einen Backup-Job erstellt; daher kann sie nicht gleichzeitig eine Continuous Data Protection (CDP)-Task aktiviert haben.", + "ORG_ZSTACK_STORAGE_CDP_10122": "Die VM [UUID: %s] ist durch die CDP-Aufgabe [UUID: %s] geschützt; daher kann die CBT-Aufgabe nicht gleichzeitig %s werden.", + "ORG_ZSTACK_STORAGE_CDP_10123": "Der Scheduler-Job [Typ: %s] für die Ressource [UUID: %s] kann nicht erstellt werden, weil die VM [UUID: %s] durch die CDP-Aufgabe [UUID: %s] geschützt ist.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "IPMI-Adresse und Port existieren bereits.", "ORG_ZSTACK_STORAGE_CDP_10044": "Die Zuweisung virtueller Ressourcen sollte größer sein als die Zuweisung physischer Ressourcen.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "Bitte stellen Sie Folgendes sicher, um eine Verbindung zum Bare-Metal-Server herzustellen: 1. Verifizieren Sie, dass die IPMI-Schnittstelle aktiv ist; 2. Bestätigen Sie, dass die IPMI-Adresse, der Port, der Benutzername und das Passwort korrekt sind; 3. Stellen Sie sicher, dass IPMI über LAN in den BIOS-Einstellungen aktiviert ist.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-en_US.json b/conf/i18n/globalErrorCodeMapping/global-error-en_US.json index 8fda69f4152..86934bf1e8f 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-en_US.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-en_US.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "no primary storage[uuid:%s] exists", "ORG_ZSTACK_V2V_10019": "primary storage with UUID:%s is not supported for virtual machine migration v2v", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "failed to transition volume snapshot [uuid:%s, name:%s] due to status event [%s]", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "Cannot enable %s task for VM [UUID: %s] while chain-type snapshot [UUID: %s] is changing.", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "failed to retrieve volume[uuid:%s, installPath:%s] size from primary storage[uuid:%s], due to %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "failed to retrieve volume[uuid:%s, installPath:%s] size from primary storage[uuid:%s], %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s] is not in a Running, Paused, Destroyed, or Stopped state; current state[%s]", @@ -2655,6 +2656,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "Backup storage [UUID: %s] is not connected to the cloud environment. Please ensure it is properly configured and integrated.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s] is not a baremetal cluster configuration.", "ORG_ZSTACK_STORAGE_CDP_10042": "The VM [UUID: %s] has already created a backup job; therefore, it cannot have a Continuous Data Protection (CDP) task enabled simultaneously.", + "ORG_ZSTACK_STORAGE_CDP_10122": "VM [UUID: %s] is protected by CDP task [UUID: %s]; therefore, the CBT task cannot be %s at the same time.", + "ORG_ZSTACK_STORAGE_CDP_10123": "Cannot create scheduler job [type: %s] for resource [UUID: %s] because VM [UUID: %s] is protected by CDP task [UUID: %s].", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "IPMI Address and Port already exists.", "ORG_ZSTACK_STORAGE_CDP_10044": "Virtual resource allocation should be larger than physical resource allocation", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "Please ensure the following to establish a connection to the bare-metal server: 1. Verify that the IPMI interface is active; 2. Confirm that the IPMI address, port, username, and password are accurate; 3. Ensure that IPMI over LAN is enabled in the BIOS settings.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json b/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json index a0e299aff9f..3818c34afee 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "aucun stockage principal [uuid:%s] n'existe", "ORG_ZSTACK_V2V_10019": "le stockage principal avec UUID:%s n'est pas pris en charge pour la migration de machine virtuelle v2v", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "Échec de la transition de l'instantané de volume [uuid:%s, name:%s] en raison de l'événement d'état [%s]", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "Impossible d'activer la tâche %s pour la VM [UUID : %s] pendant la modification de l'instantané de type chaîne [UUID : %s].", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "Échec de la récupération de la taille du volume [uuid:%s, installPath:%s] à partir du stockage principal [uuid:%s], dû à %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "Échec de la récupération de la taille du volume [uuid:%s, installPath:%s] à partir du stockage principal [uuid:%s], %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm [uuid:%s] n'est pas dans un état En cours d'exécution, En pause, Détruit ou Arrêté ; état actuel [%s]", @@ -2650,6 +2651,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "Le stockage de sauvegarde [UUID: %s] n'est pas connecté à l'environnement cloud. Veuillez vous assurer qu'il est correctement configuré et intégré.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s] n'est pas une configuration de cluster baremetal.", "ORG_ZSTACK_STORAGE_CDP_10042": "La VM [UUID: %s] a déjà créé un travail de sauvegarde ; par conséquent, elle ne peut pas avoir de tâche de protection continue des données (CDP) activée simultanément.", + "ORG_ZSTACK_STORAGE_CDP_10122": "La VM [UUID: %s] est protégée par la tâche CDP [UUID: %s] ; la tâche CBT ne peut donc pas être %s simultanément.", + "ORG_ZSTACK_STORAGE_CDP_10123": "Impossible de créer la tâche planifiée [type : %s] pour la ressource [UUID : %s], car la VM [UUID : %s] est protégée par la tâche CDP [UUID : %s].", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "L'adresse et le port IPMI existent déjà.", "ORG_ZSTACK_STORAGE_CDP_10044": "L'allocation de ressources virtuelles doit être supérieure à l'allocation de ressources physiques", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "Veuillez vous assurer des points suivants pour établir une connexion au serveur bare-metal : 1. Vérifiez que l'interface IPMI est active ; 2. Confirmez que l'adresse IPMI, le port, le nom d'utilisateur et le mot de passe sont corrects ; 3. Assurez-vous que IPMI over LAN est activé dans les paramètres BIOS.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json b/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json index d27b78d3499..c5affa9c4cd 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "tidak ada primary storage[uuid:%s] yang ada", "ORG_ZSTACK_V2V_10019": "primary storage dengan UUID:%s tidak didukung untuk migrasi mesin virtual v2v", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "gagal melakukan transisi volume snapshot [uuid:%s, name:%s] karena status event [%s]", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "Tidak dapat mengaktifkan tugas %s untuk VM [UUID: %s] saat snapshot bertipe rantai [UUID: %s] sedang berubah.", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "gagal mengambil ukuran volume[uuid:%s, installPath:%s] dari primary storage[uuid:%s], karena %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "gagal mengambil ukuran volume[uuid:%s, installPath:%s] dari primary storage[uuid:%s], %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s] tidak dalam keadaan Running, Paused, Destroyed, atau Stopped; keadaan saat ini[%s]", @@ -2650,6 +2651,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "Penyimpanan cadangan [UUID: %s] tidak terhubung ke lingkungan cloud. Pastikan sudah dikonfigurasi dan diintegrasikan dengan benar.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s] bukan konfigurasi cluster baremetal.", "ORG_ZSTACK_STORAGE_CDP_10042": "VM [UUID: %s] sudah memiliki pekerjaan cadangan; oleh karena itu, tidak dapat memiliki tugas Continuous Data Protection (CDP) yang diaktifkan secara bersamaan.", + "ORG_ZSTACK_STORAGE_CDP_10122": "VM [UUID: %s] dilindungi oleh tugas CDP [UUID: %s]; oleh karena itu, tugas CBT tidak dapat di-%s pada saat yang sama.", + "ORG_ZSTACK_STORAGE_CDP_10123": "Tidak dapat membuat tugas terjadwal [tipe: %s] untuk sumber daya [UUID: %s] karena VM [UUID: %s] dilindungi oleh tugas CDP [UUID: %s].", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "Alamat dan Port IPMI sudah ada.", "ORG_ZSTACK_STORAGE_CDP_10044": "Alokasi sumber daya virtual harus lebih besar dari alokasi sumber daya fisik", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "Pastikan hal berikut untuk建立 koneksi ke server bare-metal: 1. Verifikasi bahwa interface IPMI aktif; 2. Konfirmasi bahwa alamat IPMI, port, nama pengguna, dan kata sandi akurat; 3. Pastikan IPMI over LAN diaktifkan di pengaturan BIOS.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json b/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json index 4acbf1c06e4..013258169ae 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "プライマリストレージ[uuid:%s]が存在しません", "ORG_ZSTACK_V2V_10019": "UUID:%s のプライマリストレージは仮想マシンの移行v2vでサポートされていません", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "ボリュームスナップショット[uuid:%s, name:%s]のステータスの問題により失敗しました", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "%s タスクは、VM [UUID: %s] のチェーン型スナップショット [UUID: %s] の変更中は有効にできません。", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "プライマリストレージ[uuid:%s]からボリューム[uuid:%s, installPath:%s]のサイズを取得できませんでした。理由: %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "プライマリストレージ[uuid:%s]からボリューム[uuid:%s, installPath:%s]のサイズを取得できませんでした。%s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s]は実行中、一時停止、破棄、または停止状態ではありません。現在の状態[%s]", @@ -2650,6 +2651,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "バックアップストレージ[UUID: %s]はクラウド環境に接続されていません。適切に設定され統合されていることを確認してください。", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s]はベアメタルクラスタ構成ではありません。", "ORG_ZSTACK_STORAGE_CDP_10042": "VM[UUID: %s]は既にバックアップ job が作成されているため、Continuous Data Protection(CDP)タスクを同時に有効にすることはできません。", + "ORG_ZSTACK_STORAGE_CDP_10122": "VM [UUID: %s] は CDP タスク [UUID: %s] で保護されているため、CBT タスクを同時に %s できません。", + "ORG_ZSTACK_STORAGE_CDP_10123": "タイプ %s、リソース [UUID: %s] のスケジューラージョブは、VM [UUID: %s] が CDP タスク [UUID: %s] で保護されているため作成できません。", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "IPMIアドレスとポートは既に存在します。", "ORG_ZSTACK_STORAGE_CDP_10044": "仮想リソースの割り当ては物理リソースの割り当てより大きくなければなりません", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "ベアメタルサーバーへの接続を確立するには、以下を確認してください: 1. IPMIインターフェースがアクティブであることを確認します; 2. IPMIアドレス、ポート、ユーザー名、パスワードが正しいことを確認します; 3. BIOS設定でIPMI over LANが有効になっていることを確認します。", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json b/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json index d9d5de55de9..33f37462941 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "기본 스토리지[uuid:%s]가 존재하지 않습니다", "ORG_ZSTACK_V2V_10019": "UUID:%s의 기본 스토리지는 가상 머신 마이그레이션 v2v에 지원되지 않습니다", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "상태 이벤트 [%s]로 인해 볼륨 스냅샷 [uuid:%s, name:%s] 전환 실패", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "%s 태스크는 VM [UUID: %s]의 체인형 스냅샷 [UUID: %s]이(가) 변경 중인 동안 활성화할 수 없습니다.", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "기본 스토리지[uuid:%s]에서 볼륨[uuid:%s, installPath:%s] 크기를 검색하지 못함, 원인: %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "기본 스토리지[uuid:%s]에서 볼륨[uuid:%s, installPath:%s] 크기를 검색하지 못함, %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s]은 Running, Paused, Destroyed, 또는 Stopped 상태가 아닙니다; 현재 상태[%s]", @@ -2560,6 +2561,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "백업 스토리지 [UUID: %s]가 클라우드 환경에 연결되어 있지 않습니다. 올바르게 구성 및 통합되어 있는지 확인해 주세요.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s]는 베어메탈 클러스터 구성이 아닙니다.", "ORG_ZSTACK_STORAGE_CDP_10042": "VM [UUID: %s]에 이미 백업 작업이 생성되어 있어, 동시에 연속 데이터 보호(CDP) 작업을 활성화할 수 없습니다.", + "ORG_ZSTACK_STORAGE_CDP_10122": "VM [UUID: %s]이(가) CDP 태스크 [UUID: %s]로 보호되고 있으므로 CBT 태스크를 동시에 %s할 수 없습니다.", + "ORG_ZSTACK_STORAGE_CDP_10123": "유형 %s, 리소스 [UUID: %s]의 스케줄러 작업은 VM [UUID: %s]이(가) CDP 태스크 [UUID: %s]로 보호되고 있으므로 생성할 수 없습니다.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "IPMI 주소와 포트가 이미 존재합니다.", "ORG_ZSTACK_STORAGE_CDP_10044": "가상 리소스 할당은 물리적 리소스 할당보다 커야 합니다.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "베어메탈 서버에 연결하려면 다음을 확인해 주세요: 1. IPMI 인터페이스가 활성화되어 있는지 확인; 2. IPMI 주소, 포트, 사용자 이름 및 비밀번호가 정확한지 확인; 3. BIOS 설정에서 IPMI over LAN이 활성화되어 있는지 확인.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json b/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json index 2bcbcfe039e..843237c86f8 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "Первичное хранилище[uuid:%s] не существует", "ORG_ZSTACK_V2V_10019": "Первичное хранилище с UUID:%s не поддерживается для миграции виртуальных машин v2v", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "Не удалось перейти к снимку тома [uuid:%s, name:%s] из-за события статуса [%s]", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "Невозможно включить задачу %s для ВМ [UUID: %s], пока изменяется цепочечный снимок [UUID: %s].", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "Не удалось получить размер тома[uuid:%s, installPath:%s] с первичного хранилища[uuid:%s], из-за %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "Не удалось получить размер тома[uuid:%s, installPath:%s] с первичного хранилища[uuid:%s], %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "Виртуальная машина[uuid:%s] не находится в состоянии Running, Paused, Destroyed или Stopped; текущее состояние[%s]", @@ -2650,6 +2651,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "Хранилище резервных копий [UUID: %s] не подключено к облачной среде. Пожалуйста, убедитесь, что оно правильно настроено и интегрировано.", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Кластер[uuid:%s] не является конфигурацией baremetal кластера.", "ORG_ZSTACK_STORAGE_CDP_10042": "Для ВМ [UUID: %s] уже создано задание резервного копирования; поэтому для нее не может быть одновременно включена задача непрерывной защиты данных (CDP).", + "ORG_ZSTACK_STORAGE_CDP_10122": "ВМ [UUID: %s] защищена задачей CDP [UUID: %s]; поэтому задача CBT не может быть одновременно %s.", + "ORG_ZSTACK_STORAGE_CDP_10123": "Невозможно создать задание планировщика [тип: %s] для ресурса [UUID: %s], поскольку ВМ [UUID: %s] защищена задачей CDP [UUID: %s].", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "Адрес и порт IPMI уже существуют.", "ORG_ZSTACK_STORAGE_CDP_10044": "Выделение виртуальных ресурсов должно быть больше, чем выделение физических ресурсов", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "Пожалуйста, выполните следующие условия для подключения к bare-metal серверу: 1. Проверьте, что интерфейс IPMI активен; 2. Убедитесь, что адрес IPMI, порт, имя пользователя и пароль указаны верно; 3. Убедитесь, что IPMI over LAN включен в настройках BIOS.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json b/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json index 3c8c04b2cf7..a9d183e136c 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "ไม่มี primary storage[uuid:%s] อยู่", "ORG_ZSTACK_V2V_10019": "primary storage ที่มี UUID:%s ไม่รองรับสำหรับการย้าย virtual machine v2v", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "ล้มเหลวในการเปลี่ยนสถานะ volume snapshot [uuid:%s, name:%s] เนื่องจาก status event [%s]", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "ไม่สามารถเปิดใช้งานงาน %s สำหรับ VM [UUID: %s] ขณะที่สแนปช็อตประเภทเชน [UUID: %s] กำลังเปลี่ยนแปลง", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "ล้มเหลวในการดึงขนาด volume[uuid:%s, installPath:%s] จาก primary storage[uuid:%s], เนื่องจาก %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "ล้มเหลวในการดึงขนาด volume[uuid:%s, installPath:%s] จาก primary storage[uuid:%s], %s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s] ไม่ได้อยู่ในสถานะ Running, Paused, Destroyed หรือ Stopped; สถานะปัจจุบัน[%s]", @@ -2650,6 +2651,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "พื้นที่จัดเก็บข้อมูลสำรอง [UUID: %s] ไม่ได้เชื่อมต่อกับสภาพแวดล้อมคลาวด์ โปรดตรวจสอบให้มีการกำหนดค่าและบูรณาการอย่างถูกต้อง", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "Cluster[uuid:%s] ไม่ใช่การกำหนดค่าคลัสเตอร์เซิร์ฟเวอร์แท้", "ORG_ZSTACK_STORAGE_CDP_10042": "VM [UUID: %s] ได้สร้างงานสำรองข้อมูลแล้ว ดังนั้นจึงไม่สามารถเปิดใช้งานงาน CDP พร้อมกันได้", + "ORG_ZSTACK_STORAGE_CDP_10122": "VM [UUID: %s] ได้รับการปกป้องโดยงาน CDP [UUID: %s] ดังนั้นจึงไม่สามารถ %s งาน CBT พร้อมกันได้", + "ORG_ZSTACK_STORAGE_CDP_10123": "ไม่สามารถสร้างงานตามกำหนดเวลา [ประเภท: %s] สำหรับทรัพยากร [UUID: %s] ได้ เนื่องจาก VM [UUID: %s] ได้รับการปกป้องโดยงาน CDP [UUID: %s]", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "ที่อยู่ IPMI และพอร์ตมีอยู่แล้ว", "ORG_ZSTACK_STORAGE_CDP_10044": "การจัดสรรทรัพยากรเสมือนควรมากกว่าการจัดสรรทรัพยากรทางกายภาพ", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "โปรดตรวจสอบสิ่งต่อไปนี้เพื่อสร้างการเชื่อมต่อกับเซิร์ฟเวอร์แท้: 1. ยืนยันว่าอินเทอร์เฟซ IPMI ทำงานอยู่ 2. ยืนยันว่าที่อยู่ IPMI พอร์ต ชื่อผู้ใช้ และรหัสผ่านถูกต้อง 3. ตรวจสอบว่า IPMI over LAN เปิดใช้งานอยู่ในการตั้งค่า BIOS", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json b/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json index 0c36ae4980b..938422b8d99 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "未找到主存储[uuid:%s]", "ORG_ZSTACK_V2V_10019": "主要存储[uuid:%s]不支持v2v迁移", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "失败于通过状态事件[%s]更改卷快照[%s:%s]的状态", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "无法启用%s任务:虚拟机[UUID: %s]的链类型快照[UUID: %s]正在变更。", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "无法在主存储[uuid:%s]上获取卷[uuid:%s, 安装路径:%s]的大小,因为%s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "失败在主要存储[uuid:%s]上获取卷[uuid:%s, 安装路径:%s]的大小,%s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s] 没有运行、暂停或销毁、停止、正在销毁,当前状态[%s]", @@ -2655,6 +2656,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "备份存储[uuid: %s]未连接", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "集群[uuid:%s]不是一个裸金属集群。", "ORG_ZSTACK_STORAGE_CDP_10042": "该虚拟机[uuid: %s]已创建备份任务,无法同时启用CDP任务。", + "ORG_ZSTACK_STORAGE_CDP_10122": "虚拟机[UUID: %s]已受CDP任务[UUID: %s]保护,因此无法同时%s CBT任务。", + "ORG_ZSTACK_STORAGE_CDP_10123": "无法创建类型为%s、资源[UUID: %s]的定时任务,因为虚拟机[UUID: %s]已受CDP任务[UUID: %s]保护。", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "IPMI地址和端口 %s:%d 已经存在。", "ORG_ZSTACK_STORAGE_CDP_10044": "\u0027%s\u0027(%d) 应大于 \u0027%s\u0027(%d)", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "无法到达裸金属机箱,请确保:1. IPMI 连接是激活的;2. IPMI 地址、端口、用户名和密码正确;3. BIOS 中启用了 IPMI Over LAN。", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json b/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json index 16f440db0ea..b7b0b012b05 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json @@ -19,6 +19,7 @@ "ORG_ZSTACK_STORAGE_PRIMARY_10039": "未找到主儲儲[uuid:%s]", "ORG_ZSTACK_V2V_10019": "主要儲儲[uuid:%s]不支持v2v迁移", "ORG_ZSTACK_STORAGE_SNAPSHOT_10007": "失敗於通過状态事件[%s]更改卷快照[%s:%s]的状态", + "ORG_ZSTACK_STORAGE_SNAPSHOT_10030": "無法啟用%s任務:虛擬機[UUID: %s]的鏈類型快照[UUID: %s]正在變更。", "ORG_ZSTACK_STORAGE_SNAPSHOT_10006": "無法在主儲儲[uuid:%s]上獲取卷[uuid:%s, 安装路径:%s]的大小,因为%s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10005": "失敗在主要儲儲[uuid:%s]上獲取卷[uuid:%s, 安装路径:%s]的大小,%s", "ORG_ZSTACK_STORAGE_SNAPSHOT_10004": "vm[uuid:%s] 没有運行、暫停或销毁、停止、正在销毁,當前状态[%s]", @@ -2650,6 +2651,8 @@ "ORG_ZSTACK_STORAGE_CDP_10041": "备份儲儲[uuid: %s]未連接", "ORG_ZSTACK_BAREMETAL_CHASSIS_10005": "叢叢[uuid:%s]不是一個裸金属叢叢。", "ORG_ZSTACK_STORAGE_CDP_10042": "該虚拟機[uuid: %s]已創建备份任務,無法同时啟用CDP任務。", + "ORG_ZSTACK_STORAGE_CDP_10122": "虛擬機[UUID: %s]已受CDP任務[UUID: %s]保護,因此無法同時%s CBT任務。", + "ORG_ZSTACK_STORAGE_CDP_10123": "無法建立類型為%s、資源[UUID: %s]的排程任務,因為虛擬機[UUID: %s]已受CDP任務[UUID: %s]保護。", "ORG_ZSTACK_BAREMETAL_CHASSIS_10007": "IPMI地址和端口 %s:%d 已经儲在。", "ORG_ZSTACK_STORAGE_CDP_10044": "'%s'(%d) 应大於 '%s'(%d)", "ORG_ZSTACK_BAREMETAL_CHASSIS_10001": "無法到達裸金属機箱,請確保:1. IPMI 連接是激活的;2. IPMI 地址、端口、用戶名和密碼正確;3. BIOS 中啟用了 IPMI Over LAN。", diff --git a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java index 9fc175de2c1..8498d5a9205 100644 --- a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java +++ b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java @@ -1400,6 +1400,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_SNAPSHOT_10029 = "ORG_ZSTACK_STORAGE_SNAPSHOT_10029"; + public static final String ORG_ZSTACK_STORAGE_SNAPSHOT_10030 = "ORG_ZSTACK_STORAGE_SNAPSHOT_10030"; + public static final String ORG_ZSTACK_ZWATCH_NAMESPACE_10000 = "ORG_ZSTACK_ZWATCH_NAMESPACE_10000"; public static final String ORG_ZSTACK_ZWATCH_NAMESPACE_10001 = "ORG_ZSTACK_ZWATCH_NAMESPACE_10001"; @@ -7522,6 +7524,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_CDP_10121 = "ORG_ZSTACK_STORAGE_CDP_10121"; + public static final String ORG_ZSTACK_STORAGE_CDP_10122 = "ORG_ZSTACK_STORAGE_CDP_10122"; + + public static final String ORG_ZSTACK_STORAGE_CDP_10123 = "ORG_ZSTACK_STORAGE_CDP_10123"; + public static final String ORG_ZSTACK_SNS_PLATFORM_EMAIL_10000 = "ORG_ZSTACK_SNS_PLATFORM_EMAIL_10000"; public static final String ORG_ZSTACK_SNS_PLATFORM_EMAIL_10001 = "ORG_ZSTACK_SNS_PLATFORM_EMAIL_10001"; From cef2558fc9e095bf27eb8b357533503c23e58af4 Mon Sep 17 00:00:00 2001 From: "yingzhe.hu" Date: Thu, 20 Aug 2026 18:24:43 +0800 Subject: [PATCH 2/3] [snapshot]: serialize VM snapshot admission Route chain snapshot admission by vmUuid and use the shared per-VM backup operation queue. Resolves: ZSTAC-86666 Change-Id: Idfd94627a050fab22032f6d66f243ba3e4926320 --- .../snapshot/VolumeSnapshotConstant.java | 1 + .../snapshot/VolumeSnapshotManagerImpl.java | 176 +++++++++++++++++- .../snapshot/VolumeSnapshotTreeBase.java | 136 ++++++++++---- .../org/zstack/storage/volume/VolumeBase.java | 9 +- 4 files changed, 280 insertions(+), 42 deletions(-) diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java index 8f784a72051..1709443176a 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java @@ -14,6 +14,7 @@ public interface VolumeSnapshotConstant { String SNAPSHOT_UUID = "SNAPSHOT_UUID"; String VOLUME_SNAPSHOT_STRUCT = "VolumeSnapshotStruct"; + String VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE = "backup-operation-vm-%s"; String NEED_TAKE_SNAPSHOTS_ON_HYPERVISOR = "needTakeSnapshotOnHypervisor"; String NEED_BLOCK_STREAM_ON_HYPERVISOR = "needBlockStreamOnHypervisor"; } diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java index 6555a9b404f..f19bce9372b 100755 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java @@ -13,6 +13,8 @@ import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; @@ -86,6 +88,8 @@ public class VolumeSnapshotManagerImpl extends AbstractService implements @Autowired private CloudBus bus; @Autowired + private ResourceDestinationMaker destMaker; + @Autowired private DatabaseFacade dbf; @Autowired private AccountManager acntMgr; @@ -112,6 +116,9 @@ private void passThrough(VolumeSnapshotMessage msg) { "cannot find volume snapshot[uuid:%s]", msg.getSnapshotUuid() )); } + if (routeSnapshotDeleteToVm(msg, vo)) { + return; + } if (msg.getVolumeUuid() != null) { VolumeSnapshotTreeBase tree = new VolumeSnapshotTreeBase(vo, true); @@ -125,6 +132,19 @@ private void passThrough(VolumeSnapshotMessage msg) { } } + private boolean routeSnapshotDeleteToVm(VolumeSnapshotMessage msg, VolumeSnapshotVO snapshot) { + if (!(msg instanceof APIDeleteVolumeSnapshotMsg) + && !(msg instanceof DeleteVolumeSnapshotMsg) + && !(msg instanceof VolumeSnapshotDeletionMsg)) { + return false; + } + if (snapshot.getVolumeUuid() == null) { + return false; + } + + return routeToVmIfNeeded((Message) msg, getVmUuidByVolumeUuid(snapshot.getVolumeUuid())); + } + private void passThrough(VolumeSnapshotGroupMessage msg) { VolumeSnapshotGroupVO vo = dbf.findByUuid(msg.getGroupUuid(), VolumeSnapshotGroupVO.class); if (vo == null) { @@ -155,11 +175,14 @@ public void handleMessage(Message msg) { private void handleLocalMessage(Message msg) { if (msg instanceof CreateVolumeSnapshotMsg) { - handle((CreateVolumeSnapshotMsg) msg); + CreateVolumeSnapshotMsg cmsg = (CreateVolumeSnapshotMsg) msg; + if (!routeCreateSnapshotToVm(cmsg)) { + handle(cmsg); + } } else if (msg instanceof VolumeSnapshotReportPrimaryStorageCapacityUsageMsg) { handle((VolumeSnapshotReportPrimaryStorageCapacityUsageMsg) msg); } else if (msg instanceof MarkVolumeAsSnapshotMsg) { - handle((MarkVolumeAsSnapshotMsg) msg); + handleMarkVolumeAsSnapshot((MarkVolumeAsSnapshotMsg) msg); } else if (msg instanceof AskVolumeSnapshotStructMsg) { handle((AskVolumeSnapshotStructMsg) msg); } else if (msg instanceof GetVolumeSnapshotTreeRootNodeMsg) { @@ -171,6 +194,66 @@ private void handleLocalMessage(Message msg) { } } + private boolean routeCreateSnapshotToVm(CreateVolumeSnapshotMsg msg) { + return routeToVmIfNeeded(msg, getVmUuidByVolumeUuid(msg.getVolumeUuid())); + } + + private void handleMarkVolumeAsSnapshot(MarkVolumeAsSnapshotMsg msg) { + String vmUuid = msg.getVolume().getVmInstanceUuid(); + if (vmUuid == null) { + vmUuid = getVmUuidByVolumeUuid(msg.getVolume().getUuid()); + } + if (routeToVmIfNeeded(msg, vmUuid)) { + return; + } + if (vmUuid == null) { + handle(msg, null); + return; + } + + String finalVmUuid = vmUuid; + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, finalVmUuid); + } + + @Override + public void run(SyncTaskChain chain) { + try { + handle(msg, chain); + } catch (Exception t) { + MarkVolumeAsSnapshotReply reply = new MarkVolumeAsSnapshotReply(); + reply.setError(errf.throwableToOperationError(t)); + bus.reply(msg, reply); + chain.next(); + } + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + + private String getVmUuidByVolumeUuid(String volumeUuid) { + return Q.New(VolumeVO.class) + .select(VolumeVO_.vmInstanceUuid) + .eq(VolumeVO_.uuid, volumeUuid) + .findValue(); + } + + private boolean routeToVmIfNeeded(Message msg, String vmUuid) { + if (vmUuid == null || destMaker.isManagedByUs(vmUuid)) { + return false; + } + + bus.makeTargetServiceIdByResourceUuid(msg, VolumeSnapshotConstant.SERVICE_ID, vmUuid); + bus.route(msg); + return true; + } + private void handle(GetVolumeSnapshotEncryptedMsg msg) { GetVolumeSnapshotEncryptedReply snapshotEncryptedReply = new GetVolumeSnapshotEncryptedReply(); GetVolumeSnapshotEncryptedOnPrimaryStorageMsg encryptedMsg = new GetVolumeSnapshotEncryptedOnPrimaryStorageMsg(); @@ -741,6 +824,42 @@ public VolumeSnapshotInventory syncVolumeSnapshotDBAfterTakeSnapshot(VolumeInven } private void handle(final AskVolumeSnapshotStructMsg msg) { + String vmUuid = getVmUuidByVolumeUuid(msg.getVolumeUuid()); + if (routeToVmIfNeeded(msg, vmUuid)) { + return; + } + if (vmUuid == null) { + replyVolumeSnapshotStruct(msg); + return; + } + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, vmUuid); + } + + @Override + public void run(SyncTaskChain chain) { + try { + replyVolumeSnapshotStruct(msg); + } catch (Exception t) { + AskVolumeSnapshotStructReply reply = new AskVolumeSnapshotStructReply(); + reply.setError(errf.throwableToOperationError(t)); + bus.reply(msg, reply); + } finally { + chain.next(); + } + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + + private void replyVolumeSnapshotStruct(AskVolumeSnapshotStructMsg msg) { AskVolumeSnapshotStructReply reply = new AskVolumeSnapshotStructReply(); CreateVolumeSnapshotMsg cmsg = new CreateVolumeSnapshotMsg(); cmsg.setResourceUuid(msg.getResourceUuid()); @@ -831,8 +950,36 @@ public void setup() { String __name__ = "create-new-tree-if-needed"; @Override public void run(FlowTrigger trigger, Map data) { - struct = getVolumeSnapshotStruct(msg); - trigger.next(); + if (volumeVO.getVmInstanceUuid() == null) { + struct = getVolumeSnapshotStruct(msg); + trigger.next(); + return; + } + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, + volumeVO.getVmInstanceUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + try { + struct = getVolumeSnapshotStruct(msg); + trigger.next(); + } catch (Exception t) { + trigger.fail(errf.throwableToOperationError(t)); + } finally { + chain.next(); + } + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); } }); @@ -1086,7 +1233,7 @@ private VolumeSnapshotStatus getCurrentSnapshotStatus(String uuid) { .findValue(); } - private void handle(MarkVolumeAsSnapshotMsg msg) { + private void handle(MarkVolumeAsSnapshotMsg msg, SyncTaskChain admissionChain) { final MarkVolumeAsSnapshotReply ret = new MarkVolumeAsSnapshotReply(); VolumeInventory vol = msg.getVolume(); @@ -1094,6 +1241,9 @@ private void handle(MarkVolumeAsSnapshotMsg msg) { if (psType == null) { ret.setError(operr(ORG_ZSTACK_STORAGE_SNAPSHOT_10015, "cannot find type for primaryStorage [%s]", vol.getPrimaryStorageUuid())); bus.reply(msg, ret); + if (admissionChain != null) { + admissionChain.next(); + } return; } @@ -1220,7 +1370,13 @@ public void handle(Map data) { new FireSnapShotCanonicalEvent(). fireSnapShotStatusChangedEvent(svo.getStatus(), VolumeSnapshotInventory.valueOf(svo)); ret.setInventory(VolumeSnapshotInventory.valueOf(svo)); - bus.reply(msg, ret); + try { + bus.reply(msg, ret); + } finally { + if (admissionChain != null) { + admissionChain.next(); + } + } } }); @@ -1229,7 +1385,13 @@ public void handle(Map data) { public void handle(ErrorCode errCode, Map data) { rollbackSnapshot(vo.getUuid()); ret.setError(errCode); - bus.reply(msg, ret); + try { + bus.reply(msg, ret); + } finally { + if (admissionChain != null) { + admissionChain.next(); + } + } } }); } diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java index 13a67af0970..289a83bf200 100755 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java @@ -464,6 +464,109 @@ public void done(ErrorCodeList errorCodeList) { } }); + flow(new Flow() { + String __name__ = String.format("change-volume-snapshot-status-%s", VolumeSnapshotStatus.Deleting); + + private List snapshots() { + return Objects.equals(msg.getScope(), DeleteVolumeSnapshotScope.Single.toString()) + ? Collections.singletonList(VolumeSnapshotInventory.valueOf(currentRoot)) + : currentLeaf.getDescendants(); + } + + private void changeStatus(FlowTrigger trigger) { + changeStatusOfSnapshots(StatusEvent.delete, snapshots(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + if (msg.isDbOnly() || msg.isVolumeDeletion() || volume == null + || volume.getVmInstanceUuid() == null) { + changeStatus(trigger); + return; + } + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, + volume.getVmInstanceUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + try { + AskVolumeSnapshotCapabilityMsg askMsg = new AskVolumeSnapshotCapabilityMsg(); + askMsg.setPrimaryStorageUuid(volume.getPrimaryStorageUuid()); + askMsg.setVolume(VolumeInventory.valueOf(volume)); + bus.makeLocalServiceId(askMsg, PrimaryStorageConstant.SERVICE_ID); + MessageReply reply = bus.call(askMsg); + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + chain.next(); + return; + } + + changeStatusOfSnapshots(StatusEvent.delete, snapshots(), new Completion(chain) { + @Override + public void success() { + try { + trigger.next(); + } finally { + chain.next(); + } + } + + @Override + public void fail(ErrorCode errorCode) { + try { + trigger.fail(errorCode); + } finally { + chain.next(); + } + } + }); + } catch (Exception t) { + try { + trigger.fail(errf.throwableToOperationError(t)); + } finally { + chain.next(); + } + } + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + changeStatusOfSnapshots(StatusEvent.ready, snapshots(), new Completion(trigger) { + @Override + public void success() { + trigger.rollback(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.rollback(); + } + }); + } + }); + if (Objects.equals(msg.getScope(), DeleteVolumeSnapshotScope.Single.toString())) { deleteSingleFlows(); } else { @@ -559,39 +662,6 @@ public void handle(ErrorCode errCode, Map data) { } private void deleteChainFlows() { - flow(new Flow() { - String __name__ = String.format("change-volume-snapshot-status-%s", VolumeSnapshotStatus.Deleting); - - public void run(final FlowTrigger trigger, Map data) { - changeStatusOfSnapshots(StatusEvent.delete, currentLeaf.getDescendants(), new Completion(trigger) { - @Override - public void success() { - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - - @Override - public void rollback(final FlowRollback trigger, Map data) { - changeStatusOfSnapshots(StatusEvent.ready, currentLeaf.getDescendants(), new Completion(trigger) { - @Override - public void success() { - trigger.rollback(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.rollback(); - } - }); - } - }); - if (!msg.isVolumeDeletion()) { // this deletion is caused by snapshot deletion, check if merge need SimpleQuery tq = dbf.createQuery(VolumeSnapshotTreeVO.class); diff --git a/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java b/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java index 2e87e6b41e8..765628b52e8 100755 --- a/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java +++ b/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java @@ -276,7 +276,7 @@ public void run(final FlowTrigger trigger, Map data) { rootVolumeInventory.setName(String.format("reimage-vm-point-%s-%s", msg.getVmInstanceUuid(), TimeUtils.getCurrentTimeStamp("yyyyMMddHHmmss"))); gmsg.setVolume(rootVolumeInventory); gmsg.setAccountUuid(msg.getAccountUuid()); - bus.makeLocalServiceId(gmsg, VolumeSnapshotConstant.SERVICE_ID); + bus.makeTargetServiceIdByResourceUuid(gmsg, VolumeSnapshotConstant.SERVICE_ID, msg.getVmInstanceUuid()); bus.send(gmsg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { @@ -477,7 +477,12 @@ public void run(final FlowTrigger trigger, Map data) { dataVolumeInventory.setName(String.format("reinit-data-vol-point-%s-%s", self.getUuid(), TimeUtils.getCurrentTimeStamp("yyyyMMddHHmmss"))); gmsg.setVolume(dataVolumeInventory); gmsg.setAccountUuid(msg.getSession().getAccountUuid()); - bus.makeLocalServiceId(gmsg, VolumeSnapshotConstant.SERVICE_ID); + if (dataVolumeInventory.getVmInstanceUuid() == null) { + bus.makeLocalServiceId(gmsg, VolumeSnapshotConstant.SERVICE_ID); + } else { + bus.makeTargetServiceIdByResourceUuid(gmsg, VolumeSnapshotConstant.SERVICE_ID, + dataVolumeInventory.getVmInstanceUuid()); + } bus.send(gmsg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { From 5aa04b07dc6d19f9aa3d128df1a27da005e4c912 Mon Sep 17 00:00:00 2001 From: "yingzhe.hu" Date: Fri, 21 Aug 2026 18:39:00 +0800 Subject: [PATCH 3/3] [backup]: queue backup messages by VM Route internal protection messages through BackupMessage by VM UUID. Serialize them on the owning MN and preserve timeout budgets. Keep API routing unchanged and remove feature-local VM queues and locks. Resolves: ZSTAC-86666 Change-Id: I4cdfd46e5dd3ff4853edd6298771704eecaa8841 --- conf/springConfigXml/BackupStorageManager.xml | 6 + .../core/timeout/ApiTimeoutManagerImpl.java | 6 + .../header/storage/backup/BackupMessage.java | 48 +++++ .../snapshot/VolumeSnapshotConstant.java | 1 - .../storage/backup/BackupMessageManager.java | 10 + .../backup/BackupMessageManagerImpl.java | 124 ++++++++++++ .../snapshot/VolumeSnapshotManagerImpl.java | 185 +++--------------- .../snapshot/VolumeSnapshotTreeBase.java | 61 +----- .../org/zstack/storage/volume/VolumeBase.java | 9 +- 9 files changed, 224 insertions(+), 226 deletions(-) create mode 100644 header/src/main/java/org/zstack/header/storage/backup/BackupMessage.java create mode 100644 storage/src/main/java/org/zstack/storage/backup/BackupMessageManager.java create mode 100644 storage/src/main/java/org/zstack/storage/backup/BackupMessageManagerImpl.java diff --git a/conf/springConfigXml/BackupStorageManager.xml b/conf/springConfigXml/BackupStorageManager.xml index 41915f46295..afd753897f0 100755 --- a/conf/springConfigXml/BackupStorageManager.xml +++ b/conf/springConfigXml/BackupStorageManager.xml @@ -21,6 +21,12 @@ + + + + + + diff --git a/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java b/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java index 32648038afe..6d75655999c 100755 --- a/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java +++ b/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java @@ -343,7 +343,13 @@ public Long getTimeoutSeconds() { @Override public void setMessageTimeout(Message msg) { if (msg instanceof ConfigurableTimeoutMessage) { + long existingDeadline = ((ConfigurableTimeoutMessage) msg).getMessageDeadline(); MessageTimeoutDsc mtd = evalTimeout(getMessageTimeout((ConfigurableTimeoutMessage) msg)); + if (existingDeadline != -1) { + mtd.setMessageDeadline(Math.min(existingDeadline, mtd.getMessageDeadline())); + mtd.setMessageTimeout(Math.min(mtd.getMessageTimeout(), + Math.max(1L, mtd.getMessageDeadline() - timer.getCurrentTimeMillis()))); + } ((ConfigurableTimeoutMessage) msg).setTimeout(mtd.getMessageTimeout()); ((ConfigurableTimeoutMessage) msg).setMessageDeadline(mtd.getMessageDeadline()); } else if (msg instanceof NeedReplyMessage) { diff --git a/header/src/main/java/org/zstack/header/storage/backup/BackupMessage.java b/header/src/main/java/org/zstack/header/storage/backup/BackupMessage.java new file mode 100644 index 00000000000..ae9d3c6d3db --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/BackupMessage.java @@ -0,0 +1,48 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.message.OverlayMessage; +import org.zstack.header.vm.VmInstanceMessage; + +public class BackupMessage extends OverlayMessage implements VmInstanceMessage { + public static final String SERVICE_ID = "backup-message"; + private static final String QUEUED_HEADER = BackupMessage.class.getName() + ".queued"; + public static final String SYNC_SIGNATURE = "backup-operation-vm-%s"; + + private String vmInstanceUuid; + private String targetServiceId; + + public static BackupMessage valueOf(String vmUuid, String targetServiceId, NeedReplyMessage innerMessage) { + innerMessage.putHeaderEntry(QUEUED_HEADER, true); + + BackupMessage msg = new BackupMessage(); + msg.setVmInstanceUuid(vmUuid); + msg.setTargetServiceId(targetServiceId); + msg.setMessage(innerMessage); + msg.setMessageDeadline(innerMessage.getMessageDeadline()); + msg.setTimeout(innerMessage.getMessageDeadline() == -1 ? innerMessage.getTimeout() : + Math.max(1L, innerMessage.getMessageDeadline() - System.currentTimeMillis())); + return msg; + } + + public static boolean hasQueued(NeedReplyMessage msg) { + return Boolean.TRUE.equals(msg.getHeaderEntry(QUEUED_HEADER)); + } + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getTargetServiceId() { + return targetServiceId; + } + + public void setTargetServiceId(String targetServiceId) { + this.targetServiceId = targetServiceId; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java index 1709443176a..8f784a72051 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java @@ -14,7 +14,6 @@ public interface VolumeSnapshotConstant { String SNAPSHOT_UUID = "SNAPSHOT_UUID"; String VOLUME_SNAPSHOT_STRUCT = "VolumeSnapshotStruct"; - String VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE = "backup-operation-vm-%s"; String NEED_TAKE_SNAPSHOTS_ON_HYPERVISOR = "needTakeSnapshotOnHypervisor"; String NEED_BLOCK_STREAM_ON_HYPERVISOR = "needBlockStreamOnHypervisor"; } diff --git a/storage/src/main/java/org/zstack/storage/backup/BackupMessageManager.java b/storage/src/main/java/org/zstack/storage/backup/BackupMessageManager.java new file mode 100644 index 00000000000..c9219f96041 --- /dev/null +++ b/storage/src/main/java/org/zstack/storage/backup/BackupMessageManager.java @@ -0,0 +1,10 @@ +package org.zstack.storage.backup; + +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.header.message.NeedReplyMessage; + +public interface BackupMessageManager { + boolean routeToQueue(NeedReplyMessage msg, String vmUuid, String targetServiceId); + + void sendToQueue(NeedReplyMessage msg, String vmUuid, String targetServiceId, CloudBusCallBack callback); +} diff --git a/storage/src/main/java/org/zstack/storage/backup/BackupMessageManagerImpl.java b/storage/src/main/java/org/zstack/storage/backup/BackupMessageManagerImpl.java new file mode 100644 index 00000000000..38f968576ee --- /dev/null +++ b/storage/src/main/java/org/zstack/storage/backup/BackupMessageManagerImpl.java @@ -0,0 +1,124 @@ +package org.zstack.storage.backup; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.AbstractService; +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.backup.BackupMessage; + +import java.util.LinkedHashMap; + +import static org.zstack.utils.clouderrorcode.CloudOperationsErrorCode.ORG_ZSTACK_CORE_CLOUDBUS_10002; + +public class BackupMessageManagerImpl extends AbstractService implements BackupMessageManager { + @Autowired + private CloudBus bus; + @Autowired + private ThreadFacade thdf; + + @Override + public boolean routeToQueue(NeedReplyMessage msg, String vmUuid, String targetServiceId) { + if (vmUuid == null || BackupMessage.hasQueued(msg)) { + return false; + } + + NeedReplyMessage originalRequest = (NeedReplyMessage) msg.clone(); + originalRequest.setHeaders(new LinkedHashMap<>(msg.getHeaders())); + sendToQueue(msg, vmUuid, targetServiceId, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + bus.reply(originalRequest, reply); + } + }); + return true; + } + + @Override + public void sendToQueue(NeedReplyMessage msg, String vmUuid, String targetServiceId, + CloudBusCallBack callback) { + BackupMessage bmsg = BackupMessage.valueOf(vmUuid, targetServiceId, msg); + bus.makeTargetServiceIdByResourceUuid(bmsg, BackupMessage.SERVICE_ID, vmUuid); + bus.send(bmsg, callback); + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof BackupMessage) { + handle((BackupMessage) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(BackupMessage msg) { + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format(BackupMessage.SYNC_SIGNATURE, msg.getVmInstanceUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + if (msg.getMessageDeadline() != -1 && + msg.getMessageDeadline() <= System.currentTimeMillis()) { + MessageReply reply = new MessageReply(); + reply.setError(Platform.touterr(ORG_ZSTACK_CORE_CLOUDBUS_10002, msg.toErrorString())); + try { + bus.reply(msg, reply); + } finally { + chain.next(); + } + return; + } + + NeedReplyMessage inner = msg.getMessage(); + inner.setId(Platform.getUuid()); + if (inner.getMessageDeadline() == -1) { + inner.setMessageDeadline(msg.getMessageDeadline()); + } + if (inner.getMessageDeadline() != -1) { + inner.setTimeout(Math.max(1L, + inner.getMessageDeadline() - System.currentTimeMillis())); + } + bus.makeLocalServiceId(inner, msg.getTargetServiceId()); + bus.send(inner, new CloudBusCallBack(msg, chain) { + @Override + public void run(MessageReply reply) { + try { + bus.reply(msg, reply); + } finally { + chain.next(); + } + } + }); + } + + @Override + public String getName() { + return msg.getTaskName(); + } + }); + } + + @Override + public String getId() { + return bus.makeLocalServiceId(BackupMessage.SERVICE_ID); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java index f19bce9372b..a5ec868cd19 100755 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java @@ -13,8 +13,6 @@ import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.core.thread.ChainTask; -import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; @@ -45,6 +43,7 @@ import org.zstack.storage.snapshot.group.VolumeSnapshotGroupChecker; import org.zstack.storage.snapshot.reference.VolumeSnapshotReferenceTreeBase; import org.zstack.storage.snapshot.reference.VolumeSnapshotReferenceUtils; +import org.zstack.storage.backup.BackupMessageManager; import org.zstack.storage.volume.FireSnapShotCanonicalEvent; import org.zstack.storage.volume.VolumeSystemTags; import org.zstack.tag.TagManager; @@ -88,8 +87,6 @@ public class VolumeSnapshotManagerImpl extends AbstractService implements @Autowired private CloudBus bus; @Autowired - private ResourceDestinationMaker destMaker; - @Autowired private DatabaseFacade dbf; @Autowired private AccountManager acntMgr; @@ -105,6 +102,8 @@ public class VolumeSnapshotManagerImpl extends AbstractService implements private CascadeFacade casf; @Autowired private VmInstanceDeviceManager vidm; + @Autowired + private BackupMessageManager backupMessageManager; private Map referenceFactories = Collections.synchronizedMap(new HashMap<>()); @@ -116,7 +115,10 @@ private void passThrough(VolumeSnapshotMessage msg) { "cannot find volume snapshot[uuid:%s]", msg.getSnapshotUuid() )); } - if (routeSnapshotDeleteToVm(msg, vo)) { + if ((msg instanceof DeleteVolumeSnapshotMsg || msg instanceof VolumeSnapshotDeletionMsg) + && vo.getVolumeUuid() != null + && backupMessageManager.routeToQueue((NeedReplyMessage) msg, + getVmUuidByVolumeUuid(vo.getVolumeUuid()), VolumeSnapshotConstant.SERVICE_ID)) { return; } @@ -132,19 +134,6 @@ private void passThrough(VolumeSnapshotMessage msg) { } } - private boolean routeSnapshotDeleteToVm(VolumeSnapshotMessage msg, VolumeSnapshotVO snapshot) { - if (!(msg instanceof APIDeleteVolumeSnapshotMsg) - && !(msg instanceof DeleteVolumeSnapshotMsg) - && !(msg instanceof VolumeSnapshotDeletionMsg)) { - return false; - } - if (snapshot.getVolumeUuid() == null) { - return false; - } - - return routeToVmIfNeeded((Message) msg, getVmUuidByVolumeUuid(snapshot.getVolumeUuid())); - } - private void passThrough(VolumeSnapshotGroupMessage msg) { VolumeSnapshotGroupVO vo = dbf.findByUuid(msg.getGroupUuid(), VolumeSnapshotGroupVO.class); if (vo == null) { @@ -176,15 +165,27 @@ public void handleMessage(Message msg) { private void handleLocalMessage(Message msg) { if (msg instanceof CreateVolumeSnapshotMsg) { CreateVolumeSnapshotMsg cmsg = (CreateVolumeSnapshotMsg) msg; - if (!routeCreateSnapshotToVm(cmsg)) { + if (!backupMessageManager.routeToQueue(cmsg, getVmUuidByVolumeUuid(cmsg.getVolumeUuid()), + VolumeSnapshotConstant.SERVICE_ID)) { handle(cmsg); } } else if (msg instanceof VolumeSnapshotReportPrimaryStorageCapacityUsageMsg) { handle((VolumeSnapshotReportPrimaryStorageCapacityUsageMsg) msg); } else if (msg instanceof MarkVolumeAsSnapshotMsg) { - handleMarkVolumeAsSnapshot((MarkVolumeAsSnapshotMsg) msg); + MarkVolumeAsSnapshotMsg mmsg = (MarkVolumeAsSnapshotMsg) msg; + String vmUuid = mmsg.getVolume().getVmInstanceUuid(); + if (vmUuid == null) { + vmUuid = getVmUuidByVolumeUuid(mmsg.getVolume().getUuid()); + } + if (!backupMessageManager.routeToQueue(mmsg, vmUuid, VolumeSnapshotConstant.SERVICE_ID)) { + handle(mmsg); + } } else if (msg instanceof AskVolumeSnapshotStructMsg) { - handle((AskVolumeSnapshotStructMsg) msg); + AskVolumeSnapshotStructMsg amsg = (AskVolumeSnapshotStructMsg) msg; + if (!backupMessageManager.routeToQueue(amsg, getVmUuidByVolumeUuid(amsg.getVolumeUuid()), + VolumeSnapshotConstant.SERVICE_ID)) { + handle(amsg); + } } else if (msg instanceof GetVolumeSnapshotTreeRootNodeMsg) { handle((GetVolumeSnapshotTreeRootNodeMsg) msg); } else if (msg instanceof GetVolumeSnapshotEncryptedMsg) { @@ -194,49 +195,6 @@ private void handleLocalMessage(Message msg) { } } - private boolean routeCreateSnapshotToVm(CreateVolumeSnapshotMsg msg) { - return routeToVmIfNeeded(msg, getVmUuidByVolumeUuid(msg.getVolumeUuid())); - } - - private void handleMarkVolumeAsSnapshot(MarkVolumeAsSnapshotMsg msg) { - String vmUuid = msg.getVolume().getVmInstanceUuid(); - if (vmUuid == null) { - vmUuid = getVmUuidByVolumeUuid(msg.getVolume().getUuid()); - } - if (routeToVmIfNeeded(msg, vmUuid)) { - return; - } - if (vmUuid == null) { - handle(msg, null); - return; - } - - String finalVmUuid = vmUuid; - thdf.chainSubmit(new ChainTask(msg) { - @Override - public String getSyncSignature() { - return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, finalVmUuid); - } - - @Override - public void run(SyncTaskChain chain) { - try { - handle(msg, chain); - } catch (Exception t) { - MarkVolumeAsSnapshotReply reply = new MarkVolumeAsSnapshotReply(); - reply.setError(errf.throwableToOperationError(t)); - bus.reply(msg, reply); - chain.next(); - } - } - - @Override - public String getName() { - return getSyncSignature(); - } - }); - } - private String getVmUuidByVolumeUuid(String volumeUuid) { return Q.New(VolumeVO.class) .select(VolumeVO_.vmInstanceUuid) @@ -244,16 +202,6 @@ private String getVmUuidByVolumeUuid(String volumeUuid) { .findValue(); } - private boolean routeToVmIfNeeded(Message msg, String vmUuid) { - if (vmUuid == null || destMaker.isManagedByUs(vmUuid)) { - return false; - } - - bus.makeTargetServiceIdByResourceUuid(msg, VolumeSnapshotConstant.SERVICE_ID, vmUuid); - bus.route(msg); - return true; - } - private void handle(GetVolumeSnapshotEncryptedMsg msg) { GetVolumeSnapshotEncryptedReply snapshotEncryptedReply = new GetVolumeSnapshotEncryptedReply(); GetVolumeSnapshotEncryptedOnPrimaryStorageMsg encryptedMsg = new GetVolumeSnapshotEncryptedOnPrimaryStorageMsg(); @@ -824,42 +772,6 @@ public VolumeSnapshotInventory syncVolumeSnapshotDBAfterTakeSnapshot(VolumeInven } private void handle(final AskVolumeSnapshotStructMsg msg) { - String vmUuid = getVmUuidByVolumeUuid(msg.getVolumeUuid()); - if (routeToVmIfNeeded(msg, vmUuid)) { - return; - } - if (vmUuid == null) { - replyVolumeSnapshotStruct(msg); - return; - } - - thdf.chainSubmit(new ChainTask(msg) { - @Override - public String getSyncSignature() { - return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, vmUuid); - } - - @Override - public void run(SyncTaskChain chain) { - try { - replyVolumeSnapshotStruct(msg); - } catch (Exception t) { - AskVolumeSnapshotStructReply reply = new AskVolumeSnapshotStructReply(); - reply.setError(errf.throwableToOperationError(t)); - bus.reply(msg, reply); - } finally { - chain.next(); - } - } - - @Override - public String getName() { - return getSyncSignature(); - } - }); - } - - private void replyVolumeSnapshotStruct(AskVolumeSnapshotStructMsg msg) { AskVolumeSnapshotStructReply reply = new AskVolumeSnapshotStructReply(); CreateVolumeSnapshotMsg cmsg = new CreateVolumeSnapshotMsg(); cmsg.setResourceUuid(msg.getResourceUuid()); @@ -950,36 +862,8 @@ public void setup() { String __name__ = "create-new-tree-if-needed"; @Override public void run(FlowTrigger trigger, Map data) { - if (volumeVO.getVmInstanceUuid() == null) { - struct = getVolumeSnapshotStruct(msg); - trigger.next(); - return; - } - - thdf.chainSubmit(new ChainTask(msg) { - @Override - public String getSyncSignature() { - return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, - volumeVO.getVmInstanceUuid()); - } - - @Override - public void run(SyncTaskChain chain) { - try { - struct = getVolumeSnapshotStruct(msg); - trigger.next(); - } catch (Exception t) { - trigger.fail(errf.throwableToOperationError(t)); - } finally { - chain.next(); - } - } - - @Override - public String getName() { - return getSyncSignature(); - } - }); + struct = getVolumeSnapshotStruct(msg); + trigger.next(); } }); @@ -1233,7 +1117,7 @@ private VolumeSnapshotStatus getCurrentSnapshotStatus(String uuid) { .findValue(); } - private void handle(MarkVolumeAsSnapshotMsg msg, SyncTaskChain admissionChain) { + private void handle(MarkVolumeAsSnapshotMsg msg) { final MarkVolumeAsSnapshotReply ret = new MarkVolumeAsSnapshotReply(); VolumeInventory vol = msg.getVolume(); @@ -1241,9 +1125,6 @@ private void handle(MarkVolumeAsSnapshotMsg msg, SyncTaskChain admissionChain) { if (psType == null) { ret.setError(operr(ORG_ZSTACK_STORAGE_SNAPSHOT_10015, "cannot find type for primaryStorage [%s]", vol.getPrimaryStorageUuid())); bus.reply(msg, ret); - if (admissionChain != null) { - admissionChain.next(); - } return; } @@ -1370,13 +1251,7 @@ public void handle(Map data) { new FireSnapShotCanonicalEvent(). fireSnapShotStatusChangedEvent(svo.getStatus(), VolumeSnapshotInventory.valueOf(svo)); ret.setInventory(VolumeSnapshotInventory.valueOf(svo)); - try { - bus.reply(msg, ret); - } finally { - if (admissionChain != null) { - admissionChain.next(); - } - } + bus.reply(msg, ret); } }); @@ -1385,13 +1260,7 @@ public void handle(Map data) { public void handle(ErrorCode errCode, Map data) { rollbackSnapshot(vo.getUuid()); ret.setError(errCode); - try { - bus.reply(msg, ret); - } finally { - if (admissionChain != null) { - admissionChain.next(); - } - } + bus.reply(msg, ret); } }); } diff --git a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java index 289a83bf200..78b16b60054 100755 --- a/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java +++ b/storage/src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java @@ -489,66 +489,7 @@ public void fail(ErrorCode errorCode) { @Override public void run(FlowTrigger trigger, Map data) { - if (msg.isDbOnly() || msg.isVolumeDeletion() || volume == null - || volume.getVmInstanceUuid() == null) { - changeStatus(trigger); - return; - } - - thdf.chainSubmit(new ChainTask(msg) { - @Override - public String getSyncSignature() { - return String.format(VolumeSnapshotConstant.VM_DATA_PROTECTION_OPERATION_SYNC_SIGNATURE, - volume.getVmInstanceUuid()); - } - - @Override - public void run(SyncTaskChain chain) { - try { - AskVolumeSnapshotCapabilityMsg askMsg = new AskVolumeSnapshotCapabilityMsg(); - askMsg.setPrimaryStorageUuid(volume.getPrimaryStorageUuid()); - askMsg.setVolume(VolumeInventory.valueOf(volume)); - bus.makeLocalServiceId(askMsg, PrimaryStorageConstant.SERVICE_ID); - MessageReply reply = bus.call(askMsg); - if (!reply.isSuccess()) { - trigger.fail(reply.getError()); - chain.next(); - return; - } - - changeStatusOfSnapshots(StatusEvent.delete, snapshots(), new Completion(chain) { - @Override - public void success() { - try { - trigger.next(); - } finally { - chain.next(); - } - } - - @Override - public void fail(ErrorCode errorCode) { - try { - trigger.fail(errorCode); - } finally { - chain.next(); - } - } - }); - } catch (Exception t) { - try { - trigger.fail(errf.throwableToOperationError(t)); - } finally { - chain.next(); - } - } - } - - @Override - public String getName() { - return getSyncSignature(); - } - }); + changeStatus(trigger); } @Override diff --git a/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java b/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java index 765628b52e8..2e87e6b41e8 100755 --- a/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java +++ b/storage/src/main/java/org/zstack/storage/volume/VolumeBase.java @@ -276,7 +276,7 @@ public void run(final FlowTrigger trigger, Map data) { rootVolumeInventory.setName(String.format("reimage-vm-point-%s-%s", msg.getVmInstanceUuid(), TimeUtils.getCurrentTimeStamp("yyyyMMddHHmmss"))); gmsg.setVolume(rootVolumeInventory); gmsg.setAccountUuid(msg.getAccountUuid()); - bus.makeTargetServiceIdByResourceUuid(gmsg, VolumeSnapshotConstant.SERVICE_ID, msg.getVmInstanceUuid()); + bus.makeLocalServiceId(gmsg, VolumeSnapshotConstant.SERVICE_ID); bus.send(gmsg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { @@ -477,12 +477,7 @@ public void run(final FlowTrigger trigger, Map data) { dataVolumeInventory.setName(String.format("reinit-data-vol-point-%s-%s", self.getUuid(), TimeUtils.getCurrentTimeStamp("yyyyMMddHHmmss"))); gmsg.setVolume(dataVolumeInventory); gmsg.setAccountUuid(msg.getSession().getAccountUuid()); - if (dataVolumeInventory.getVmInstanceUuid() == null) { - bus.makeLocalServiceId(gmsg, VolumeSnapshotConstant.SERVICE_ID); - } else { - bus.makeTargetServiceIdByResourceUuid(gmsg, VolumeSnapshotConstant.SERVICE_ID, - dataVolumeInventory.getVmInstanceUuid()); - } + bus.makeLocalServiceId(gmsg, VolumeSnapshotConstant.SERVICE_ID); bus.send(gmsg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) {