Skip to content

Commit 46fa446

Browse files
authored
Merge pull request #195 from MikeRayMSFT/Linux-VDI
Stage initial linux vdi sample
2 parents a6278cb + bf83233 commit 46fa446

File tree

5 files changed

+730
-0
lines changed

5 files changed

+730
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# A simple Makefile to build the VDI sample code
2+
#
3+
4+
EXECUTABLE=vdipipesample
5+
LD_FLAGS=-luuid -lrt -lpthread -lsqlvdi
6+
LD_LIBRARY_PATH=/opt/mssql/lib
7+
8+
$(EXECUTABLE): vdipipesample.cpp vdi.h vdierror.h
9+
clang++ -o $(EXECUTABLE) -g -std=c++11 vdipipesample.cpp $(LD_FLAGS) -L $(LD_LIBRARY_PATH)
10+
11+
clean:
12+
rm $(EXECUTABLE)
13+
14+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# SQLVDI for Linux
2+
This folder contains the latest files and samples required to build a SQL Server VDI based backup/restore application for Linux.
3+
4+
## Files available
5+
1. vdi.h
6+
2. vdierror.h
7+
3. vdipipesample.cpp
8+
4. MAKEFILE
9+
10+
## Known Bugs
11+
12+
There is a problem with VDF_LikeDisk and VDF_RandomAccess where the backup/restore is aborted unexpectedly.
13+
14+
## Steps
15+
16+
1. Install the mssql-server and mssql-tools packages 
17+
18+
[Install SQL Server on Linux](http://docs.microsoft.com/sql/linux/sql-server-linux-setup) 
19+
[Install SQL Server tools on Linux](http://docs.microsoft.com/sql/linux/sql-server-linux-setup-tools) 
20+
 
21+
1. Install the clang and uuid-dev packages in order to build the sample.
22+
23+
Example (for Ubuntu): 
24+
25+
```bash
26+
sudo apt-get install clang 
27+
sudo apt-get install uuid-dev 
28+
```
29+
30+
1. Create a symbolic link to sqlcmd in /usr/bin
31+
32+
```bash
33+
sudo ln -s /opt/mssql-tools/bin/sqlcmd /usr/bin/sqlcmd
34+
```
35+
36+
1. Copy the vdi sample files to a directory on your Linux machine.
37+
38+
1. Run make to build the sample code
39+
40+
1. Run the vdi client as the mssql user or follow these instructions:
41+
42+
- Add the user running the vdi client to mssql group `sudo usermod -a -G mssql vdiuser`.
43+
- Add the mssql user to the vdi client user's group `sudo usermod -a -G vdiuser mssql`.
44+
- Reboot
45+
46+
1. Run the following command to issue a database backup of pubs:
47+
48+
```bash
49+
LD_LIBRARY_PATH="/opt/mssql/lib" ./vdipipesample B D pubs sa <SQLSAPASSWORD> /tmp/pubs.bak
50+
```
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
//*********************************************************************
2+
// Copyright (C) Microsoft Corporation.
3+
//
4+
// @File: vdi.h
5+
// @Owner: <owner alias>
6+
//
7+
// Purpose:
8+
// <description>
9+
//
10+
// Notes:
11+
// <special-instructions>
12+
//
13+
//*********************************************************************
14+
#ifndef __vdi_h__
15+
#define __vdi_h__
16+
17+
#pragma once
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
#pragma pack(push, _vdi_h_)
24+
25+
#include <time.h>
26+
#include <stdint.h>
27+
28+
// Errors that need to be passed back to SQL Server, originally defined
29+
// in Windows.h or similar
30+
//
31+
#define ERROR_SUCCESS 0L
32+
#define ERROR_ARENA_TRASHED 7L
33+
#define ERROR_HANDLE_EOF 38L
34+
#define ERROR_HANDLE_DISK_FULL 39L
35+
#define ERROR_NOT_SUPPORTED 50L
36+
#define ERROR_DISK_FULL 112L
37+
#define ERROR_OPERATION_ABORTED 995L
38+
39+
#pragma pack(8)
40+
struct VDConfig
41+
{
42+
uint32_t deviceCount;
43+
uint32_t features;
44+
uint32_t prefixZoneSize;
45+
uint32_t alignment;
46+
uint32_t softFileMarkBlockSize;
47+
uint32_t EOMWarningSize;
48+
uint32_t serverTimeOut;
49+
uint32_t blockSize;
50+
uint32_t maxIODepth;
51+
uint32_t maxTransferSize;
52+
uint32_t bufferAreaSize;
53+
};
54+
55+
enum VDFeatures
56+
{ VDF_Removable = 0x1,
57+
VDF_Rewind = 0x2,
58+
VDF_Position = 0x10,
59+
VDF_SkipBlocks = 0x20,
60+
VDF_ReversePosition = 0x40,
61+
VDF_Discard = 0x80,
62+
VDF_FileMarks = 0x100,
63+
VDF_RandomAccess = 0x200,
64+
VDF_SnapshotPrepare = 0x400,
65+
VDF_EnumFrozenFiles = 0x800,
66+
VDF_VSSWriter = 0x1000,
67+
VDF_RequestComplete = 0x2000,
68+
VDF_WriteMedia = 0x10000,
69+
VDF_ReadMedia = 0x20000,
70+
VDF_CompleteEnabled = 0x40000,
71+
VDF_LatchStats = 0x80000000,
72+
VDF_LikePipe = 0,
73+
VDF_LikeTape =
74+
( ( ( ( ( VDF_FileMarks | VDF_Removable ) | VDF_Rewind ) | VDF_Position ) |
75+
VDF_SkipBlocks ) | VDF_ReversePosition ),
76+
VDF_LikeDisk = VDF_RandomAccess};
77+
78+
enum VDCommands
79+
{ VDC_Read = 1,
80+
VDC_Write = ( VDC_Read + 1 ),
81+
VDC_ClearError = ( VDC_Write + 1 ),
82+
VDC_Rewind = ( VDC_ClearError + 1 ),
83+
VDC_WriteMark = ( VDC_Rewind + 1 ),
84+
VDC_SkipMarks = ( VDC_WriteMark + 1 ),
85+
VDC_SkipBlocks = ( VDC_SkipMarks + 1 ),
86+
VDC_Load = ( VDC_SkipBlocks + 1 ),
87+
VDC_GetPosition = ( VDC_Load + 1 ),
88+
VDC_SetPosition = ( VDC_GetPosition + 1 ),
89+
VDC_Discard = ( VDC_SetPosition + 1 ),
90+
VDC_Flush = ( VDC_Discard + 1 ),
91+
VDC_Snapshot = ( VDC_Flush + 1 ),
92+
VDC_MountSnapshot = ( VDC_Snapshot + 1 ),
93+
VDC_PrepareToFreeze = ( VDC_MountSnapshot + 1 ),
94+
VDC_FileInfoBegin = ( VDC_PrepareToFreeze + 1 ),
95+
VDC_FileInfoEnd = ( VDC_FileInfoBegin + 1 ),
96+
VDC_GetError = (VDC_FileInfoEnd + 1),
97+
VDC_Complete = (VDC_GetError + 1)};
98+
99+
enum VDWhence
100+
{ VDC_Beginning = 0,
101+
VDC_Current = ( VDC_Beginning + 1 ),
102+
VDC_End = ( VDC_Current + 1 )};
103+
104+
struct VDC_Command
105+
{
106+
int32_t commandCode;
107+
int32_t size;
108+
int64_t position;
109+
uint8_t* buffer;
110+
};
111+
112+
struct VDS_Command
113+
{
114+
int32_t commandCode;
115+
int32_t size;
116+
int64_t inPosition;
117+
int64_t outPosition;
118+
uint8_t* buffer;
119+
uint8_t* completionRoutine;
120+
uint8_t* completionContext;
121+
int32_t completionCode;
122+
int32_t bytesTransferred;
123+
};
124+
125+
//----------------------------------------------------------------------------
126+
// NAME: ClientVirtualDevice
127+
//
128+
// PURPOSE:
129+
//
130+
// Implement the ClientVirtualDevice component.
131+
//
132+
class CVDS;
133+
class CVD;
134+
class ClientVirtualDeviceSet;
135+
136+
class ClientVirtualDevice
137+
{
138+
public:
139+
ClientVirtualDevice();
140+
141+
~ClientVirtualDevice();
142+
143+
int
144+
GetCommand(
145+
time_t timeOut,
146+
VDC_Command** ppCmd);
147+
148+
int
149+
CompleteCommand(
150+
VDC_Command* pCmd,
151+
int completionCode,
152+
unsigned long bytesTransferred,
153+
int64_t position);
154+
155+
private:
156+
CVD* cvd;
157+
friend class ClientVirtualDeviceSet;
158+
};
159+
160+
//----------------------------------------------------------------------------
161+
// NAME: ClientVirtualDeviceSet
162+
//
163+
// PURPOSE:
164+
//
165+
// Implement the ClientVirtualDeviceSet component.
166+
//
167+
168+
class ClientVirtualDeviceSet
169+
{
170+
public:
171+
int
172+
Create(
173+
char* name,
174+
VDConfig* cfg);
175+
176+
int
177+
GetConfiguration(
178+
time_t timeout,
179+
VDConfig* cfg);
180+
181+
int
182+
OpenDevice(
183+
char* name,
184+
ClientVirtualDevice** ppVirtualDevice);
185+
186+
int
187+
Close();
188+
189+
int
190+
SignalAbort();
191+
192+
int
193+
OpenInSecondary(
194+
char* setName);
195+
196+
int
197+
GetBufferHandle(
198+
uint8_t* pBuffer,
199+
unsigned int* pBufferHandle);
200+
201+
int
202+
MapBufferHandle(
203+
int dwBuffer,
204+
uint8_t** ppBuffer);
205+
206+
void
207+
RegisterDeviceClosed();
208+
209+
ClientVirtualDeviceSet ();
210+
~ClientVirtualDeviceSet ();
211+
212+
private:
213+
CVDS* cvds;
214+
};
215+
216+
#pragma pack(pop, _vdi_h_)
217+
218+
#ifdef __cplusplus
219+
}
220+
#endif
221+
222+
#endif
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//*********************************************************************
2+
// Copyright (C) Microsoft Corporation.
3+
//
4+
// @File: vdierror.h
5+
// @Owner: <owner alias>
6+
//
7+
// Purpose:
8+
// <description>
9+
//
10+
// Notes:
11+
// <special-instructions>
12+
//
13+
//*********************************************************************
14+
#ifndef VDIERROR_H_
15+
#define VDIERROR_H_
16+
//****************************************************************************
17+
// Copyright (c) Microsoft Corporation.
18+
//
19+
// vdierror.h
20+
//
21+
// Purpose:
22+
// Declare the error codes emitted by the virtual device interface.
23+
//
24+
//****************************************************************************
25+
26+
//
27+
// Create an int value from component pieces
28+
//
29+
30+
#define MAKE_HRESULT(sev, fac, code) \
31+
((int) (((unsigned long)(sev) << 31) | ((unsigned long)(fac) << 16) | ((unsigned long)(code))) )
32+
33+
//---------------------------------------------------------------------------------------
34+
// Error code handling will be done in standard COM fashion:
35+
//
36+
// an int is returned and the caller can use
37+
// SUCCEEDED(code) or FAILED(code) to determine
38+
// if the function failed or not.
39+
//
40+
41+
// Form an error code mask.
42+
// All VDI errors have 0x8077 as prefix.
43+
//
44+
#define VD_ERROR(code) MAKE_HRESULT(1, 0x77, code)
45+
46+
// The object was not open
47+
//
48+
#define VD_E_NOTOPEN VD_ERROR(2) /* 0x80770002 */
49+
50+
// The api was waiting and the timeout interval had elapsed.
51+
//
52+
#define VD_E_TIMEOUT VD_ERROR(3) /* 0x80770003 */
53+
54+
// An abort request is preventing anything except termination actions.
55+
//
56+
#define VD_E_ABORT VD_ERROR(4) /* 0x80770004 */
57+
58+
// Failed to create security environment.
59+
//
60+
#define VD_E_SECURITY VD_ERROR(5) /* 0x80770005 */
61+
62+
// An invalid parameter was supplied
63+
//
64+
#define VD_E_INVALID VD_ERROR(6) /* 0x80770006 */
65+
66+
// Failed to recognize the SQL Server instance name
67+
//
68+
#define VD_E_INSTANCE_NAME VD_ERROR(7) /* 0x80770007 */
69+
70+
// The requested configuration is invalid
71+
//
72+
#define VD_E_NOTSUPPORTED VD_ERROR(9) /* 0x80770009 */
73+
74+
// Out of memory
75+
//
76+
#define VD_E_MEMORY VD_ERROR(10) /* 0x8077000a */
77+
78+
// Unexpected internal error
79+
//
80+
#define VD_E_UNEXPECTED VD_ERROR(11) /* 0x8077000b */
81+
82+
// Protocol error
83+
//
84+
#define VD_E_PROTOCOL VD_ERROR(12) /* 0x8077000c */
85+
86+
// All devices are open
87+
//
88+
#define VD_E_OPEN VD_ERROR(13) /* 0x8077000d */
89+
90+
// the object is now closed
91+
//
92+
#define VD_E_CLOSE VD_ERROR(14) /* 0x8077000e */
93+
94+
// the resource is busy
95+
//
96+
#define VD_E_BUSY VD_ERROR(15) /* 0x8077000f */
97+
98+
#endif

0 commit comments

Comments
 (0)