VirtualBox

source: vbox/trunk/src/VBox/Main/include/HardDisk2Impl.h@ 14143

Last change on this file since 14143 was 14143, checked in by vboxsync, 17 years ago

Main: Improved hard disk tree lock usage to avoid possible deadlocks when walking the hard disk tree upwards (from children to parents).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 9.2 KB
Line 
1/* $Id $ */
2
3/** @file
4 *
5 * VirtualBox COM class implementation
6 */
7
8/*
9 * Copyright (C) 2008 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#ifndef ____H_HARDDISK2IMPL
25#define ____H_HARDDISK2IMPL
26
27#include "VirtualBoxBase.h"
28
29#include "VirtualBoxImpl.h"
30#include "MediumImpl.h"
31
32#include <VBox/com/SupportErrorInfo.h>
33
34#include <VBox/VBoxHDD-new.h>
35
36class Progress;
37
38////////////////////////////////////////////////////////////////////////////////
39
40/**
41 * The HardDisk2 component class implements the IHardDisk2 interface.
42 */
43class ATL_NO_VTABLE HardDisk2
44 : public com::SupportErrorInfoDerived <MediumBase, HardDisk2, IHardDisk2>
45 , public VirtualBoxBaseWithTypedChildrenNEXT <HardDisk2>
46 , public VirtualBoxSupportTranslation <HardDisk2>
47 , public IHardDisk2
48{
49public:
50
51 typedef VirtualBoxBaseWithTypedChildrenNEXT <HardDisk2>::DependentChildren
52 List;
53
54 class MergeChain;
55
56 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (HardDisk2)
57
58 DECLARE_NOT_AGGREGATABLE (HardDisk2)
59
60 DECLARE_PROTECT_FINAL_CONSTRUCT()
61
62 BEGIN_COM_MAP (HardDisk2)
63 COM_INTERFACE_ENTRY (ISupportErrorInfo)
64 COM_INTERFACE_ENTRY2 (IMedium, MediumBase)
65 COM_INTERFACE_ENTRY (IHardDisk2)
66 END_COM_MAP()
67
68 NS_DECL_ISUPPORTS
69
70 DECLARE_EMPTY_CTOR_DTOR (HardDisk2)
71
72 HRESULT FinalConstruct();
73 void FinalRelease();
74
75 // public initializer/uninitializer for internal purposes only
76 HRESULT init (VirtualBox *aVirtualBox, const BSTR aFormat,
77 const BSTR aLocation);
78 HRESULT init (VirtualBox *aVirtualBox,
79 const BSTR aLocation);
80 HRESULT init (VirtualBox *aVirtualBox, HardDisk2 *aParent,
81 const settings::Key &aNode);
82 void uninit();
83
84 // IMedium properties & methods
85 COM_FORWARD_IMedium_TO_BASE (MediumBase)
86
87 // IHardDisk2 properties
88 STDMETHOD(COMGETTER(Format)) (BSTR *aFormat);
89 STDMETHOD(COMGETTER(Type)) (HardDiskType_T *aType);
90 STDMETHOD(COMSETTER(Type)) (HardDiskType_T aType);
91 STDMETHOD(COMGETTER(Parent)) (IHardDisk2 **aParent);
92 STDMETHOD(COMGETTER(Children)) (ComSafeArrayOut (IHardDisk2 *, aChildren));
93 STDMETHOD(COMGETTER(Root)) (IHardDisk2 **aRoot);
94 STDMETHOD(COMGETTER(ReadOnly)) (BOOL *aReadOnly);
95 STDMETHOD(COMGETTER(LogicalSize)) (ULONG64 *aLogicalSize);
96
97 // IHardDisk2 methods
98 STDMETHOD(CreateDynamicStorage) (ULONG64 aLogicalSize, IProgress **aProgress);
99 STDMETHOD(CreateFixedStorage) (ULONG64 aLogicalSize, IProgress **aProgress);
100 STDMETHOD(DeleteStorage) (IProgress **aProgress);
101 STDMETHOD(CreateDiffStorage) (IHardDisk2 *aTarget, IProgress **aProgress);
102 STDMETHOD(MergeTo) (INPTR GUIDPARAM aTargetId, IProgress **aProgress);
103 STDMETHOD(CloneTo) (IHardDisk2 *aTarget, IProgress **aProgress);
104 STDMETHOD(FlattenTo) (IHardDisk2 *aTarget, IProgress **aProgress);
105
106 // public methods for internal purposes only
107
108 /**
109 * Shortcut to VirtualBoxBaseWithTypedChildrenNEXT::dependentChildren().
110 */
111 const List &children() const { return dependentChildren(); }
112
113 void updatePaths (const char *aOldPath, const char *aNewPath);
114
115 ComObjPtr <HardDisk2> root (uint32_t *aLevel = NULL);
116
117 bool isReadOnly();
118
119 HRESULT saveSettings (settings::Key &aParentNode);
120
121 HRESULT compareLocationTo (const char *aLocation, int &aResult);
122
123 /**
124 * Shortcut to #deleteStorage() that doesn't wait for operation completion
125 * and implies the progress object will be used for waiting.
126 */
127 HRESULT deleteStorageNoWait (ComObjPtr <Progress> &aProgress)
128 { return deleteStorage (&aProgress, false /* aWait */); }
129
130 /**
131 * Shortcut to #deleteStorage() that wait for operation completion by
132 * blocking the current thread.
133 */
134 HRESULT deleteStorageAndWait (ComObjPtr <Progress> *aProgress = NULL)
135 { return deleteStorage (aProgress, true /* aWait */); }
136
137 /**
138 * Shortcut to #createDiffStorage() that doesn't wait for operation
139 * completion and implies the progress object will be used for waiting.
140 */
141 HRESULT createDiffStorageNoWait (ComObjPtr <HardDisk2> &aTarget,
142 ComObjPtr <Progress> &aProgress)
143 { return createDiffStorage (aTarget, &aProgress, false /* aWait */); }
144
145 /**
146 * Shortcut to #createDiffStorage() that wait for operation completion by
147 * blocking the current thread.
148 */
149 HRESULT createDiffStorageAndWait (ComObjPtr <HardDisk2> &aTarget,
150 ComObjPtr <Progress> *aProgress = NULL)
151 { return createDiffStorage (aTarget, aProgress, true /* aWait */); }
152
153 HRESULT prepareMergeTo (HardDisk2 *aTarget, MergeChain * &aChain,
154 bool aIgnoreAttachments = false);
155
156 /**
157 * Shortcut to #mergeTo() that doesn't wait for operation completion and
158 * implies the progress object will be used for waiting.
159 */
160 HRESULT mergeToNoWait (MergeChain *aChain,
161 ComObjPtr <Progress> &aProgress)
162 { return mergeTo (aChain, &aProgress, false /* aWait */); }
163
164 /**
165 * Shortcut to #mergeTo() that wait for operation completion by
166 * blocking the current thread.
167 */
168 HRESULT mergeToAndWait (MergeChain *aChain,
169 ComObjPtr <Progress> *aProgress = NULL)
170 { return mergeTo (aChain, aProgress, true /* aWait */); }
171
172 void cancelMergeTo (MergeChain *aChain);
173
174 Utf8Str name();
175
176 static bool isFileLocation (const char *aLocation);
177
178 HRESULT prepareDiscard (MergeChain * &aChain);
179 HRESULT discard (ComObjPtr <Progress> &aProgress, MergeChain *aChain);
180 void cancelDiscard (MergeChain *aChain);
181
182 // unsafe inline public methods for internal purposes only (ensure there is
183 // a caller and a read lock before calling them!)
184
185 ComObjPtr <HardDisk2> parent() const { return static_cast <HardDisk2 *> (mParent); }
186 HardDiskType_T type() const { return mm.type; }
187
188 /** For com::SupportErrorInfoImpl. */
189 static const char *ComponentName() { return "HardDisk2"; }
190
191protected:
192
193 HRESULT deleteStorage (ComObjPtr <Progress> *aProgress, bool aWait);
194
195 HRESULT createDiffStorage (ComObjPtr <HardDisk2> &aTarget,
196 ComObjPtr <Progress> *aProgress,
197 bool aWait);
198
199 HRESULT mergeTo (MergeChain *aChain,
200 ComObjPtr <Progress> *aProgress,
201 bool aWait);
202
203 /**
204 * Returns VirtualBox::hardDiskTreeHandle(), for convenience. Don't forget
205 * to follow these locking rules:
206 *
207 * 1. The write lock on this handle must be either held alone on the thread
208 * or requested *after* the VirtualBox object lock. Mixing with other
209 * locks is prohibited.
210 *
211 * 2. The read lock on this handle may be intermixed with any other lock
212 * with the exception that it must be requested *after* the VirtualBox
213 * object lock.
214 */
215 RWLockHandle *treeLock() { return mVirtualBox->hardDiskTreeHandle(); }
216
217 /** Reimplements VirtualBoxWithTypedChildren::childrenLock() to return
218 * treeLock(). */
219 RWLockHandle *childrenLock() { return treeLock(); }
220
221private:
222
223 HRESULT setLocation (const BSTR aLocation);
224 HRESULT queryInfo();
225
226 HRESULT canClose();
227 HRESULT canAttach (const Guid &aMachineId,
228 const Guid &aSnapshotId);
229
230 HRESULT unregisterWithVirtualBox();
231
232 Utf8Str vdError (int aVRC);
233
234 static DECLCALLBACK(void) vdErrorCall (void *pvUser, int rc, RT_SRC_POS_DECL,
235 const char *pszFormat, va_list va);
236
237 static DECLCALLBACK(int) vdProgressCall (PVM /* pVM */, unsigned uPercent,
238 void *pvUser);
239
240 static DECLCALLBACK(int) taskThread (RTTHREAD thread, void *pvUser);
241
242 /** weak parent */
243 ComObjPtr <HardDisk2, ComWeakRef> mParent;
244
245 struct Task;
246 friend struct Task;
247
248 struct Data
249 {
250 Data() : type (HardDiskType_Normal), logicalSize (0)
251 , implicit (false), numCreateDiffTasks (0)
252 , vdProgress (NULL) , vdDiskIfaces (NULL) {}
253
254 const Bstr format;
255
256 HardDiskType_T type;
257 uint64_t logicalSize; /*< In MBytes. */
258
259 bool implicit : 1;
260
261 uint32_t numCreateDiffTasks;
262
263 Utf8Str vdError; /*< Error remembered by the VD error callback. */
264 Progress *vdProgress; /*< Progress for the VD progress callback. */
265
266 VDINTERFACE vdIfError;
267 VDINTERFACEERROR vdIfCallsError;
268
269 VDINTERFACE vdIfProgress;
270 VDINTERFACEPROGRESS vdIfCallsProgress;
271
272 PVDINTERFACE vdDiskIfaces;
273 };
274
275 Data mm;
276};
277
278#endif /* ____H_HARDDISK2IMPL */
279
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette