Changeset 24081 in vbox for trunk/src/VBox/Frontends/VBoxManage
- Timestamp:
- Oct 26, 2009 3:04:35 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp
r23882 r24081 25 25 #include <VBox/com/com.h> 26 26 #include <VBox/com/string.h> 27 #include <VBox/com/array.h> 27 28 #include <VBox/com/ErrorInfo.h> 28 29 #include <VBox/com/errorprint.h> … … 36 37 using namespace com; 37 38 39 /** 40 * Helper function used with "VBoxManage snapshot ... dump". 41 * @param pMedium 42 * @param pThisSnapshot 43 * @param pCurrentSnapshot 44 * @param uMediumLevel 45 * @param uSnapshotLevel 46 * @return 47 */ 48 bool FindAndPrintSnapshotUsingMedium(ComPtr<IMedium> &pMedium, 49 ComPtr<ISnapshot> &pThisSnapshot, 50 ComPtr<ISnapshot> &pCurrentSnapshot, 51 uint32_t uMediumLevel, 52 uint32_t uSnapshotLevel) 53 { 54 HRESULT rc; 55 56 do 57 { 58 // get snapshot machine so we can figure out which diff image this created 59 ComPtr<IMachine> pSnapshotMachine; 60 CHECK_ERROR_BREAK(pThisSnapshot, COMGETTER(Machine)(pSnapshotMachine.asOutParam())); 61 62 // get media attachments 63 SafeIfaceArray<IMediumAttachment> aAttachments; 64 CHECK_ERROR_BREAK(pSnapshotMachine, COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aAttachments))); 65 66 bool fFound = false; 67 68 for (uint32_t i = 0; 69 i < aAttachments.size(); 70 ++i) 71 { 72 ComPtr<IMediumAttachment> pAttach(aAttachments[i]); 73 DeviceType_T type; 74 CHECK_ERROR_BREAK(pAttach, COMGETTER(Type)(&type)); 75 if (type == DeviceType_HardDisk) 76 { 77 ComPtr<IMedium> pMediumInSnapshot; 78 CHECK_ERROR_BREAK(pAttach, COMGETTER(Medium)(pMediumInSnapshot.asOutParam())); 79 80 if (pMediumInSnapshot == pMedium) 81 { 82 // get snapshot name 83 Bstr bstrSnapshotName; 84 CHECK_ERROR_BREAK(pThisSnapshot, COMGETTER(Name)(bstrSnapshotName.asOutParam())); 85 86 RTPrintf("%*s \"%ls\"\n", 87 50 + uSnapshotLevel * 2, "", // indent 88 bstrSnapshotName.raw()); 89 return true; // found 90 } 91 } 92 } 93 94 if (!fFound) 95 { 96 SafeIfaceArray<ISnapshot> aSnapshots; 97 CHECK_ERROR_BREAK(pThisSnapshot, COMGETTER(Children)(ComSafeArrayAsOutParam(aSnapshots))); 98 99 for (uint32_t i = 0; 100 i < aSnapshots.size(); 101 ++i) 102 { 103 ComPtr<ISnapshot> pChild(aSnapshots[i]); 104 if (FindAndPrintSnapshotUsingMedium(pMedium, 105 pChild, 106 pCurrentSnapshot, 107 uMediumLevel, 108 uSnapshotLevel + 1)) 109 // found: 110 break; 111 } 112 } 113 } while (0); 114 115 return false; 116 } 117 118 /** 119 * Helper function used with "VBoxManage snapshot ... dump". Called from DumpSnapshot() 120 * for each hard disk attachment found in a virtual machine. This then writes out the 121 * root (base) medium for that hard disk attachment and recurses into the children 122 * tree of that medium, correlating it with the snapshots of the machine. 123 * @param pCurrentStateMedium constant, the medium listed in the current machine data (latest diff image). 124 * @param pMedium variant, initially the base medium, then a child of the base medium when recursing. 125 * @param pRootSnapshot constant, the root snapshot of the machine, if any; this then looks into the child snapshots. 126 * @param pCurrentSnapshot constant, the machine's current snapshot (so we can mark it in the output). 127 * @param uLevel variant, the recursion level for output indentation. 128 */ 129 void DumpMediumWithChildren(ComPtr<IMedium> &pCurrentStateMedium, 130 ComPtr<IMedium> &pMedium, 131 ComPtr<ISnapshot> &pRootSnapshot, 132 ComPtr<ISnapshot> &pCurrentSnapshot, 133 uint32_t uLevel) 134 { 135 HRESULT rc; 136 do 137 { 138 // print this medium 139 Bstr bstrMediumName; 140 CHECK_ERROR_BREAK(pMedium, COMGETTER(Name)(bstrMediumName.asOutParam())); 141 RTPrintf("%*s \"%ls\"%s\n", 142 uLevel * 2, "", // indent 143 bstrMediumName.raw(), 144 (pCurrentStateMedium == pMedium) ? " (CURRENT STATE)" : ""); 145 146 // find and print the snapshot that uses this particular medium (diff image) 147 FindAndPrintSnapshotUsingMedium(pMedium, pRootSnapshot, pCurrentSnapshot, uLevel, 0); 148 149 // recurse into children 150 SafeIfaceArray<IMedium> aChildren; 151 CHECK_ERROR_BREAK(pMedium, COMGETTER(Children)(ComSafeArrayAsOutParam(aChildren))); 152 for (uint32_t i = 0; 153 i < aChildren.size(); 154 ++i) 155 { 156 ComPtr<IMedium> pChild(aChildren[i]); 157 DumpMediumWithChildren(pCurrentStateMedium, pChild, pRootSnapshot, pCurrentSnapshot, uLevel + 1); 158 } 159 } while (0); 160 } 161 162 /** 163 * Implementation for "VBoxManage snapshot ... dump". This goes thru the machine's 164 * medium attachments and calls DumpMediumWithChildren() for each hard disk medium found, 165 * which then dumps the parent/child tree of that medium together with the corresponding 166 * snapshots. 167 * @param pMachine Machine to dump snapshots for. 168 */ 169 void DumpSnapshot(ComPtr<IMachine> &pMachine) 170 { 171 HRESULT rc; 172 173 do 174 { 175 // get root snapshot 176 ComPtr<ISnapshot> pSnapshot; 177 CHECK_ERROR_BREAK(pMachine, GetSnapshot(Bstr(""), pSnapshot.asOutParam())); 178 179 // get current snapshot 180 ComPtr<ISnapshot> pCurrentSnapshot; 181 CHECK_ERROR_BREAK(pMachine, COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam())); 182 183 // get media attachments 184 SafeIfaceArray<IMediumAttachment> aAttachments; 185 CHECK_ERROR_BREAK(pMachine, COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aAttachments))); 186 for (uint32_t i = 0; 187 i < aAttachments.size(); 188 ++i) 189 { 190 ComPtr<IMediumAttachment> pAttach(aAttachments[i]); 191 DeviceType_T type; 192 CHECK_ERROR_BREAK(pAttach, COMGETTER(Type)(&type)); 193 if (type == DeviceType_HardDisk) 194 { 195 ComPtr<IMedium> pCurrentStateMedium; 196 CHECK_ERROR_BREAK(pAttach, COMGETTER(Medium)(pCurrentStateMedium.asOutParam())); 197 198 ComPtr<IMedium> pBaseMedium; 199 CHECK_ERROR_BREAK(pCurrentStateMedium, COMGETTER(Base)(pBaseMedium.asOutParam())); 200 201 Bstr bstrBaseMediumName; 202 CHECK_ERROR_BREAK(pBaseMedium, COMGETTER(Name)(bstrBaseMediumName.asOutParam())); 203 204 RTPrintf("[%RI32] Images and snapshots for medium \"%ls\"\n", i, bstrBaseMediumName.raw()); 205 206 DumpMediumWithChildren(pCurrentStateMedium, 207 pBaseMedium, 208 pSnapshot, 209 pCurrentSnapshot, 210 0); 211 } 212 } 213 } while (0); 214 } 215 216 /** 217 * Implementation for all VBoxManage snapshot ... subcommands. 218 * @param a 219 * @return 220 */ 38 221 int handleSnapshot(HandlerArg *a) 39 222 { … … 45 228 46 229 /* the first argument must be the VM */ 47 ComPtr<IMachine> machine; 230 Bstr bstrMachine(a->argv[0]); 231 ComPtr<IMachine> pMachine; 48 232 /* assume it's a UUID */ 49 rc = a->virtualBox->GetMachine( Bstr(a->argv[0]), machine.asOutParam());50 if (FAILED(rc) || ! machine)233 rc = a->virtualBox->GetMachine(bstrMachine, pMachine.asOutParam()); 234 if (FAILED(rc) || !pMachine) 51 235 { 52 236 /* must be a name */ 53 CHECK_ERROR(a->virtualBox, FindMachine( Bstr(a->argv[0]), machine.asOutParam()));237 CHECK_ERROR(a->virtualBox, FindMachine(bstrMachine, pMachine.asOutParam())); 54 238 } 55 if (! machine)239 if (!pMachine) 56 240 return 1; 57 241 Bstr guid; 58 machine->COMGETTER(Id)(guid.asOutParam());242 pMachine->COMGETTER(Id)(guid.asOutParam()); 59 243 60 244 do … … 173 357 if (!guid.isEmpty()) 174 358 { 175 CHECK_ERROR_BREAK( machine, GetSnapshot(guid, pSnapshot.asOutParam()));359 CHECK_ERROR_BREAK(pMachine, GetSnapshot(guid, pSnapshot.asOutParam())); 176 360 } 177 361 else 178 362 { 179 363 /* then it must be a name */ 180 CHECK_ERROR_BREAK( machine, FindSnapshot(Bstr(a->argv[2]), pSnapshot.asOutParam()));364 CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr(a->argv[2]), pSnapshot.asOutParam())); 181 365 pSnapshot->COMGETTER(Id)(guid.asOutParam()); 182 366 } … … 220 404 || !strcmp(a->argv[2], "-current")) 221 405 { 222 CHECK_ERROR_BREAK( machine, COMGETTER(CurrentSnapshot)(snapshot.asOutParam()));406 CHECK_ERROR_BREAK(pMachine, COMGETTER(CurrentSnapshot)(snapshot.asOutParam())); 223 407 } 224 408 else … … 228 412 if (!guid.isEmpty()) 229 413 { 230 CHECK_ERROR_BREAK( machine, GetSnapshot(guid, snapshot.asOutParam()));414 CHECK_ERROR_BREAK(pMachine, GetSnapshot(guid, snapshot.asOutParam())); 231 415 } 232 416 else 233 417 { 234 418 /* then it must be a name */ 235 CHECK_ERROR_BREAK( machine, FindSnapshot(Bstr(a->argv[2]), snapshot.asOutParam()));419 CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr(a->argv[2]), snapshot.asOutParam())); 236 420 } 237 421 } … … 291 475 if (!guid.isEmpty()) 292 476 { 293 CHECK_ERROR_BREAK( machine, GetSnapshot(guid, snapshot.asOutParam()));477 CHECK_ERROR_BREAK(pMachine, GetSnapshot(guid, snapshot.asOutParam())); 294 478 } 295 479 else 296 480 { 297 481 /* then it must be a name */ 298 CHECK_ERROR_BREAK( machine, FindSnapshot(Bstr(a->argv[2]), snapshot.asOutParam()));482 CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr(a->argv[2]), snapshot.asOutParam())); 299 483 } 300 484 301 485 /* get the machine of the given snapshot */ 302 ComPtr<IMachine> machine; 303 snapshot->COMGETTER(Machine)(machine.asOutParam()); 304 showVMInfo(a->virtualBox, machine, VMINFO_NONE, console); 486 ComPtr<IMachine> pMachine2; 487 snapshot->COMGETTER(Machine)(pMachine2.asOutParam()); 488 showVMInfo(a->virtualBox, pMachine2, VMINFO_NONE, console); 489 } 490 else if (!strcmp(a->argv[1], "dump")) // undocumented parameter to debug snapshot info 491 { 492 DumpSnapshot(pMachine); 305 493 } 306 494 else
Note:
See TracChangeset
for help on using the changeset viewer.