Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

445 lines
8.7 KiB

  1. // ***************************************************************************
  2. // Copyright (C) 2000- Microsoft Corporation.
  3. // @File: sqlsnapi.h
  4. //
  5. // PURPOSE:
  6. //
  7. // The internal include file for the sql snapshot module
  8. //
  9. // NOTES:
  10. //
  11. // HISTORY:
  12. //
  13. // @Version: Whistler/Shiloh
  14. // 66601 srs 10/05/00 NTSNAP improvements
  15. //
  16. //
  17. // @EndHeader@
  18. // ***************************************************************************
  19. #include <string>
  20. #include <vector>
  21. #include <list>
  22. #include <oledb.h>
  23. #include <oledberr.h>
  24. #include <sqloledb.h>
  25. #include "vdi.h" // interface declaration from SQLVDI kit
  26. ////////////////////////////////////////////////////////////////////////
  27. // Standard foo for file name aliasing. This code block must be after
  28. // all includes of VSS header files.
  29. //
  30. #ifdef VSS_FILE_ALIAS
  31. #undef VSS_FILE_ALIAS
  32. #endif
  33. #define VSS_FILE_ALIAS "SQLSNPIH"
  34. //
  35. ////////////////////////////////////////////////////////////////////////
  36. typedef unsigned long ULONG;
  37. typedef wchar_t WCHAR;
  38. #define TRUE 1
  39. #define FALSE 0
  40. class CLogMsg;
  41. // Unexpected, "internal" errors can be logged with some
  42. // generic international text, like "Internal error: <English servicibility text>"
  43. //
  44. // Situations we expect, for which the user needs to know should
  45. // occur with proper internationalization
  46. //
  47. // Process wide globals used by the sql modules
  48. //
  49. extern IMalloc * g_pIMalloc;
  50. //-------------------------------------------------------------------------
  51. //
  52. typedef std::wstring WString;
  53. typedef std::vector<WString> StringVector;
  54. typedef StringVector::const_iterator StringVectorIter;
  55. typedef std::list<WString> StringList;
  56. typedef StringList::const_iterator StringListIter;
  57. StringVector* EnumerateServers ();
  58. //-------------------------------------------------------------------------
  59. // Handle our simple needs for DB services.
  60. //
  61. // Useage:
  62. // - Connect : establish a connection to a given server
  63. // - SetCommand: setup the SQL text to send
  64. // - ExecCommand: execute some SQL, returns TRUE if a result set
  65. // is open and ready for retrieval
  66. // - Get*: retrieve info from the result set
  67. //
  68. // The destructor will automatically disconnect from the server.
  69. //
  70. class SqlConnection
  71. {
  72. public:
  73. SqlConnection () :
  74. m_pCommandFactory (NULL),
  75. m_pCommand (NULL),
  76. m_pRowset (NULL),
  77. m_pBuffer (NULL),
  78. m_BufferSize (0),
  79. m_hAcc (NULL),
  80. m_pAccessor (NULL),
  81. m_pBindings (NULL),
  82. m_cBindings (0)
  83. {}
  84. ~SqlConnection ();
  85. void
  86. Connect (const std::wstring& serverName);
  87. void
  88. Disconnect ();
  89. void
  90. ReleaseRowset ();
  91. void
  92. SetCommand (const std::wstring& command);
  93. BOOL
  94. ExecCommand ();
  95. StringVector*
  96. GetStringColumn ();
  97. ULONG
  98. GetServerVersion () {return m_ServerVersion;}
  99. BOOL
  100. FetchFirst ();
  101. BOOL
  102. FetchNext ();
  103. void*
  104. AccessColumn (int id);
  105. private:
  106. void LogOledbError
  107. (
  108. CVssFunctionTracer &ft,
  109. CVssDebugInfo &dbgInfo,
  110. LPCWSTR wszRoutine,
  111. CLogMsg &msg
  112. );
  113. WString m_ServerName;
  114. IDBCreateCommand* m_pCommandFactory;
  115. ICommandText* m_pCommand;
  116. IRowset* m_pRowset;
  117. ULONG m_ServerVersion;
  118. // used for the generic findfirst/findnext
  119. DBBINDING* m_pBindings;
  120. ULONG m_cBindings;
  121. BYTE* m_pBuffer;
  122. ULONG m_BufferSize;
  123. HACCESSOR m_hAcc;
  124. IAccessor* m_pAccessor;
  125. };
  126. BOOL
  127. IsServerOnline (const WCHAR* serverName);
  128. //-------------------------------------------------------------------------
  129. // In SQL2000 we'll use VDI snapshots to avoid bug 58266: thaw fails.
  130. //
  131. // We'll prepare each database by starting a BACKUP WITH SNAPSHOT.
  132. // This will require one thread per database.
  133. // The backups will stall waiting for the VDI client to pull metadata.
  134. // When the "freeze" message comes along, the controlling thread will
  135. // pull all the BACKUPs to the frozen state.
  136. // Later the "thaw" message results in gathering the "success" report
  137. // from each thread.
  138. //
  139. //
  140. class Freeze2000
  141. {
  142. public:
  143. enum VDState
  144. {
  145. Unknown=0, Created, Open, SnapshotOpen
  146. };
  147. private:
  148. class FrozenDatabase
  149. {
  150. friend Freeze2000;
  151. FrozenDatabase () :
  152. m_pContext (NULL),
  153. m_hThread (NULL),
  154. m_pIVDSet (NULL),
  155. m_pIVD (NULL),
  156. m_pSnapshotCmd (NULL),
  157. m_VDState (Unknown),
  158. m_SuccessDetected (FALSE)
  159. {}
  160. Freeze2000* m_pContext;
  161. HANDLE m_hThread;
  162. IClientVirtualDeviceSet2* m_pIVDSet;
  163. IClientVirtualDevice* m_pIVD;
  164. WString m_DbName;
  165. VDC_Command* m_pSnapshotCmd;
  166. VDState m_VDState;
  167. WCHAR m_SetName [80];
  168. bool m_SuccessDetected;
  169. };
  170. public:
  171. Freeze2000 (
  172. const WString& serverName,
  173. ULONG maxDatabases);
  174. ~Freeze2000 ();
  175. void
  176. PrepareDatabase (
  177. const WString& dbName);
  178. void
  179. WaitForPrepare ();
  180. void
  181. Freeze ();
  182. BOOL
  183. Thaw () throw ();
  184. static DWORD
  185. DatabaseThreadStart (LPVOID pContext);
  186. private:
  187. enum State {
  188. Unprepared,
  189. Preparing,
  190. Prepared,
  191. Frozen,
  192. Complete,
  193. Aborted
  194. };
  195. DWORD
  196. DatabaseThread (
  197. FrozenDatabase* pDbContext);
  198. void
  199. WaitForThreads ();
  200. void
  201. AdvanceVDState (bool toSnapshot);
  202. void // race-free method to persist an abort condition
  203. SetAbort ()
  204. {
  205. InterlockedIncrement (&m_AbortCount);
  206. }
  207. bool // return true if the freeze is aborting
  208. CheckAbort ()
  209. {
  210. return 0 != InterlockedCompareExchange (&m_AbortCount, 0, 0);
  211. }
  212. void
  213. Abort () throw ();
  214. void
  215. Lock ()
  216. {
  217. EnterCriticalSection (&m_Latch);
  218. }
  219. void
  220. Unlock ()
  221. {
  222. LeaveCriticalSection (&m_Latch);
  223. }
  224. BOOL // return TRUE if we got the lock
  225. TryLock ()
  226. {
  227. return TryEnterCriticalSection (&m_Latch);
  228. }
  229. LONG m_AbortCount;
  230. CRITICAL_SECTION m_Latch;
  231. State m_State;
  232. WString m_ServerName;
  233. GUID m_BackupId;
  234. ULONG m_NumDatabases;
  235. ULONG m_MaxDatabases;
  236. FrozenDatabase* m_pDBContext;
  237. };
  238. //-------------------------------------------------------------------------
  239. // Represent a server which can be frozen.
  240. //
  241. class FrozenServer
  242. {
  243. public:
  244. FrozenServer (const std::wstring& serverName) :
  245. m_Name (serverName),
  246. m_pFreeze2000 (NULL)
  247. {}
  248. ~FrozenServer ()
  249. {
  250. if (m_pFreeze2000)
  251. {
  252. delete m_pFreeze2000;
  253. m_pFreeze2000 = NULL;
  254. }
  255. }
  256. const std::wstring& GetName () const
  257. { return m_Name; }
  258. BOOL
  259. FindDatabasesToFreeze (
  260. CCheckPath* checker);
  261. BOOL
  262. Prepare ();
  263. BOOL
  264. Freeze ();
  265. BOOL
  266. Thaw () throw ();
  267. private:
  268. BOOL
  269. FindDatabases2000 (
  270. CCheckPath* checker);
  271. void
  272. GetDatabaseProperties (const WString& dbName,
  273. BOOL* pSimple,
  274. BOOL* pOnline);
  275. private:
  276. std::wstring m_Name;
  277. SqlConnection m_Connection;
  278. StringList m_FrozenDatabases;
  279. Freeze2000* m_pFreeze2000;
  280. };
  281. //-------------------------------------------------------------------------
  282. //
  283. class Snapshot : public CSqlSnapshot
  284. {
  285. enum Status {
  286. NotInitialized,
  287. Enumerated,
  288. Prepared,
  289. Frozen };
  290. public:
  291. HRESULT Prepare (
  292. CCheckPath* checker) throw ();
  293. HRESULT Freeze () throw ();
  294. HRESULT Thaw () throw ();
  295. Snapshot () {m_Status = NotInitialized;}
  296. ~Snapshot () throw ();
  297. private:
  298. void
  299. Deinitialize ();
  300. Status m_Status;
  301. std::list<FrozenServer*> m_FrozenServers;
  302. typedef std::list<FrozenServer*>::iterator ServerIter;
  303. };
  304. // We'll use very simple exception handling.
  305. //
  306. #define THROW_GENERIC throw exception ();
  307. //----------------------------------------------------------
  308. // Implement our simple enumeration service
  309. //
  310. class SqlEnumerator : public CSqlEnumerator
  311. {
  312. enum Status {
  313. Unknown = 0,
  314. DatabaseQueryActive,
  315. FileQueryActive
  316. };
  317. public:
  318. ~SqlEnumerator () throw ();
  319. SqlEnumerator () :
  320. m_State (Unknown),
  321. m_pServers (NULL)
  322. {}
  323. HRESULT FirstServer (
  324. ServerInfo* pServer) throw ();
  325. HRESULT NextServer (
  326. ServerInfo* pServer) throw ();
  327. HRESULT FirstDatabase (
  328. const WCHAR* pServerName,
  329. DatabaseInfo* pDbInfo) throw ();
  330. HRESULT NextDatabase (
  331. DatabaseInfo* pDbInfo) throw ();
  332. HRESULT FirstFile (
  333. const WCHAR* pServerName,
  334. const WCHAR* pDbName,
  335. DatabaseFileInfo* pDbInfo) throw ();
  336. HRESULT NextFile (
  337. DatabaseFileInfo* pDbInfo) throw ();
  338. private:
  339. Status m_State;
  340. SqlConnection m_Connection;
  341. StringVector* m_pServers;
  342. int m_CurrServer;
  343. };
  344. #if defined (DEBUG)
  345. // Type of assertion passed through to utassert_fail function.
  346. //
  347. #define DBG_ASSERT(exp) BS_ASSERT(exp)
  348. // Allow for noop 64 bit asserts on win32 for things like
  349. // overflowing 32 bit long, etc.
  350. //
  351. #ifdef _WIN64
  352. #define DBG64_ASSERT(exp) BS_ASSERT(exp)
  353. #else
  354. #define DBG64_ASSERT(exp)
  355. #endif
  356. #else
  357. #define DBG_ASSERT(exp)
  358. #define DBG64_ASSERT(exp)
  359. #define DBG_ASSERTSZ(exp, txt)
  360. #endif