If we can't even get the current device mapper driver version, then
we cleanly fail the devmapper driver as not supported and fall back
on the next one.
Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
... | ... |
@@ -17,6 +17,7 @@ import ( |
17 | 17 |
"syscall" |
18 | 18 |
"time" |
19 | 19 |
|
20 |
+ "github.com/dotcloud/docker/daemon/graphdriver" |
|
20 | 21 |
"github.com/dotcloud/docker/pkg/label" |
21 | 22 |
"github.com/dotcloud/docker/utils" |
22 | 23 |
) |
... | ... |
@@ -506,6 +507,12 @@ func (devices *DeviceSet) ResizePool(size int64) error { |
506 | 506 |
func (devices *DeviceSet) initDevmapper(doInit bool) error { |
507 | 507 |
logInit(devices) |
508 | 508 |
|
509 |
+ _, err := getDriverVersion() |
|
510 |
+ if err != nil { |
|
511 |
+ // Can't even get driver version, assume not supported |
|
512 |
+ return graphdriver.ErrNotSupported |
|
513 |
+ } |
|
514 |
+ |
|
509 | 515 |
if err := os.MkdirAll(devices.metadataDir(), 0700); err != nil && !os.IsExist(err) { |
510 | 516 |
return err |
511 | 517 |
} |
... | ... |
@@ -52,6 +52,7 @@ var ( |
52 | 52 |
ErrTaskAddTarget = errors.New("dm_task_add_target failed") |
53 | 53 |
ErrTaskSetSector = errors.New("dm_task_set_sector failed") |
54 | 54 |
ErrTaskGetInfo = errors.New("dm_task_get_info failed") |
55 |
+ ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version failed") |
|
55 | 56 |
ErrTaskSetCookie = errors.New("dm_task_set_cookie failed") |
56 | 57 |
ErrNilCookie = errors.New("cookie ptr can't be nil") |
57 | 58 |
ErrAttachLoopbackDevice = errors.New("loopback mounting failed") |
... | ... |
@@ -178,6 +179,14 @@ func (t *Task) GetInfo() (*Info, error) { |
178 | 178 |
return info, nil |
179 | 179 |
} |
180 | 180 |
|
181 |
+func (t *Task) GetDriverVersion() (string, error) { |
|
182 |
+ res := DmTaskGetDriverVersion(t.unmanaged) |
|
183 |
+ if res == "" { |
|
184 |
+ return "", ErrTaskGetDriverVersion |
|
185 |
+ } |
|
186 |
+ return res, nil |
|
187 |
+} |
|
188 |
+ |
|
181 | 189 |
func (t *Task) GetNextTarget(next uintptr) (nextPtr uintptr, start uint64, |
182 | 190 |
length uint64, targetType string, params string) { |
183 | 191 |
|
... | ... |
@@ -394,6 +403,17 @@ func getInfo(name string) (*Info, error) { |
394 | 394 |
return task.GetInfo() |
395 | 395 |
} |
396 | 396 |
|
397 |
+func getDriverVersion() (string, error) { |
|
398 |
+ task := TaskCreate(DeviceVersion) |
|
399 |
+ if task == nil { |
|
400 |
+ return "", fmt.Errorf("Can't create DeviceVersion task") |
|
401 |
+ } |
|
402 |
+ if err := task.Run(); err != nil { |
|
403 |
+ return "", err |
|
404 |
+ } |
|
405 |
+ return task.GetDriverVersion() |
|
406 |
+} |
|
407 |
+ |
|
397 | 408 |
func getStatus(name string) (uint64, uint64, string, string, error) { |
398 | 409 |
task, err := createTask(DeviceStatus, name) |
399 | 410 |
if task == nil { |
... | ... |
@@ -85,23 +85,24 @@ const ( |
85 | 85 |
) |
86 | 86 |
|
87 | 87 |
var ( |
88 |
- DmGetLibraryVersion = dmGetLibraryVersionFct |
|
89 |
- DmGetNextTarget = dmGetNextTargetFct |
|
90 |
- DmLogInitVerbose = dmLogInitVerboseFct |
|
91 |
- DmSetDevDir = dmSetDevDirFct |
|
92 |
- DmTaskAddTarget = dmTaskAddTargetFct |
|
93 |
- DmTaskCreate = dmTaskCreateFct |
|
94 |
- DmTaskDestroy = dmTaskDestroyFct |
|
95 |
- DmTaskGetInfo = dmTaskGetInfoFct |
|
96 |
- DmTaskRun = dmTaskRunFct |
|
97 |
- DmTaskSetAddNode = dmTaskSetAddNodeFct |
|
98 |
- DmTaskSetCookie = dmTaskSetCookieFct |
|
99 |
- DmTaskSetMessage = dmTaskSetMessageFct |
|
100 |
- DmTaskSetName = dmTaskSetNameFct |
|
101 |
- DmTaskSetRo = dmTaskSetRoFct |
|
102 |
- DmTaskSetSector = dmTaskSetSectorFct |
|
103 |
- DmUdevWait = dmUdevWaitFct |
|
104 |
- LogWithErrnoInit = logWithErrnoInitFct |
|
88 |
+ DmGetLibraryVersion = dmGetLibraryVersionFct |
|
89 |
+ DmGetNextTarget = dmGetNextTargetFct |
|
90 |
+ DmLogInitVerbose = dmLogInitVerboseFct |
|
91 |
+ DmSetDevDir = dmSetDevDirFct |
|
92 |
+ DmTaskAddTarget = dmTaskAddTargetFct |
|
93 |
+ DmTaskCreate = dmTaskCreateFct |
|
94 |
+ DmTaskDestroy = dmTaskDestroyFct |
|
95 |
+ DmTaskGetInfo = dmTaskGetInfoFct |
|
96 |
+ DmTaskGetDriverVersion = dmTaskGetDriverVersionFct |
|
97 |
+ DmTaskRun = dmTaskRunFct |
|
98 |
+ DmTaskSetAddNode = dmTaskSetAddNodeFct |
|
99 |
+ DmTaskSetCookie = dmTaskSetCookieFct |
|
100 |
+ DmTaskSetMessage = dmTaskSetMessageFct |
|
101 |
+ DmTaskSetName = dmTaskSetNameFct |
|
102 |
+ DmTaskSetRo = dmTaskSetRoFct |
|
103 |
+ DmTaskSetSector = dmTaskSetSectorFct |
|
104 |
+ DmUdevWait = dmUdevWaitFct |
|
105 |
+ LogWithErrnoInit = logWithErrnoInitFct |
|
105 | 106 |
) |
106 | 107 |
|
107 | 108 |
func free(p *C.char) { |
... | ... |
@@ -184,6 +185,16 @@ func dmTaskGetInfoFct(task *CDmTask, info *Info) int { |
184 | 184 |
return int(C.dm_task_get_info((*C.struct_dm_task)(task), &Cinfo)) |
185 | 185 |
} |
186 | 186 |
|
187 |
+func dmTaskGetDriverVersionFct(task *CDmTask) string { |
|
188 |
+ buffer := C.malloc(128) |
|
189 |
+ defer C.free(buffer) |
|
190 |
+ res := C.dm_task_get_driver_version((*C.struct_dm_task)(task), (*C.char)(buffer), 128) |
|
191 |
+ if res == 0 { |
|
192 |
+ return "" |
|
193 |
+ } |
|
194 |
+ return C.GoString((*C.char)(buffer)) |
|
195 |
+} |
|
196 |
+ |
|
187 | 197 |
func dmGetNextTargetFct(task *CDmTask, next uintptr, start, length *uint64, target, params *string) uintptr { |
188 | 198 |
var ( |
189 | 199 |
Cstart, Clength C.uint64_t |