Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
39a7fc37
Commit
39a7fc37
authored
Jul 24, 2015
by
Mike Danese
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #11552 from jiangyaoguo/new-builder-cleaner-for-gce-pd
Refactor gec-pd to seperate builder and cleaner
parents
0b146133
27524d6b
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
84 deletions
+96
-84
gce_pd.go
pkg/volume/gce_pd/gce_pd.go
+53
-41
gce_pd_test.go
pkg/volume/gce_pd/gce_pd_test.go
+5
-5
gce_util.go
pkg/volume/gce_pd/gce_util.go
+38
-38
No files found.
pkg/volume/gce_pd/gce_pd.go
View file @
39a7fc37
...
@@ -85,18 +85,19 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
...
@@ -85,18 +85,19 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
}
}
readOnly
:=
gce
.
ReadOnly
readOnly
:=
gce
.
ReadOnly
return
&
gcePersistentDisk
{
return
&
gcePersistentDiskBuilder
{
gcePersistentDisk
:
&
gcePersistentDisk
{
podUID
:
podUID
,
podUID
:
podUID
,
volName
:
spec
.
Name
,
volName
:
spec
.
Name
,
pdName
:
pdName
,
pdName
:
pdName
,
fsType
:
fsType
,
partition
:
partition
,
partition
:
partition
,
readOnly
:
readOnly
,
manager
:
manager
,
mounter
:
mounter
,
mounter
:
mounter
,
diskMounter
:
&
gceSafeFormatAndMount
{
mounter
,
exec
.
New
()}
,
manager
:
manager
,
plugin
:
plugin
,
plugin
:
plugin
,
},
nil
},
fsType
:
fsType
,
readOnly
:
readOnly
,
diskMounter
:
&
gceSafeFormatAndMount
{
mounter
,
exec
.
New
()}},
nil
}
}
func
(
plugin
*
gcePersistentDiskPlugin
)
NewCleaner
(
volName
string
,
podUID
types
.
UID
,
mounter
mount
.
Interface
)
(
volume
.
Cleaner
,
error
)
{
func
(
plugin
*
gcePersistentDiskPlugin
)
NewCleaner
(
volName
string
,
podUID
types
.
UID
,
mounter
mount
.
Interface
)
(
volume
.
Cleaner
,
error
)
{
...
@@ -105,22 +106,21 @@ func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.U
...
@@ -105,22 +106,21 @@ func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.U
}
}
func
(
plugin
*
gcePersistentDiskPlugin
)
newCleanerInternal
(
volName
string
,
podUID
types
.
UID
,
manager
pdManager
,
mounter
mount
.
Interface
)
(
volume
.
Cleaner
,
error
)
{
func
(
plugin
*
gcePersistentDiskPlugin
)
newCleanerInternal
(
volName
string
,
podUID
types
.
UID
,
manager
pdManager
,
mounter
mount
.
Interface
)
(
volume
.
Cleaner
,
error
)
{
return
&
gcePersistentDisk
{
return
&
gcePersistentDisk
Cleaner
{
&
gcePersistentDisk
{
podUID
:
podUID
,
podUID
:
podUID
,
volName
:
volName
,
volName
:
volName
,
manager
:
manager
,
manager
:
manager
,
mounter
:
mounter
,
mounter
:
mounter
,
diskMounter
:
&
gceSafeFormatAndMount
{
mounter
,
exec
.
New
()},
plugin
:
plugin
,
plugin
:
plugin
,
},
nil
}
}
,
nil
}
}
// Abstract interface to PD operations.
// Abstract interface to PD operations.
type
pdManager
interface
{
type
pdManager
interface
{
// Attaches the disk to the kubelet's host machine.
// Attaches the disk to the kubelet's host machine.
AttachAndMountDisk
(
pd
*
gcePersistentDisk
,
globalPDPath
string
)
error
AttachAndMountDisk
(
b
*
gcePersistentDiskBuilder
,
globalPDPath
string
)
error
// Detaches the disk from the kubelet's host machine.
// Detaches the disk from the kubelet's host machine.
DetachDisk
(
pd
*
gcePersistentDisk
)
error
DetachDisk
(
c
*
gcePersistentDiskCleaner
)
error
}
}
// gcePersistentDisk volumes are disk resources provided by Google Compute Engine
// gcePersistentDisk volumes are disk resources provided by Google Compute Engine
...
@@ -130,37 +130,43 @@ type gcePersistentDisk struct {
...
@@ -130,37 +130,43 @@ type gcePersistentDisk struct {
podUID
types
.
UID
podUID
types
.
UID
// Unique identifier of the PD, used to find the disk resource in the provider.
// Unique identifier of the PD, used to find the disk resource in the provider.
pdName
string
pdName
string
// Filesystem type, optional.
fsType
string
// Specifies the partition to mount
// Specifies the partition to mount
partition
string
partition
string
// Specifies whether the disk will be attached as read-only.
readOnly
bool
// Utility interface that provides API calls to the provider to attach/detach disks.
// Utility interface that provides API calls to the provider to attach/detach disks.
manager
pdManager
manager
pdManager
// Mounter interface that provides system calls to mount the global path to the pod local path.
// Mounter interface that provides system calls to mount the global path to the pod local path.
mounter
mount
.
Interface
mounter
mount
.
Interface
// diskMounter provides the interface that is used to mount the actual block device.
diskMounter
mount
.
Interface
plugin
*
gcePersistentDiskPlugin
plugin
*
gcePersistentDiskPlugin
}
}
func
detachDiskLogError
(
pd
*
gcePersistentDisk
)
{
func
detachDiskLogError
(
pd
*
gcePersistentDisk
)
{
err
:=
pd
.
manager
.
DetachDisk
(
pd
)
err
:=
pd
.
manager
.
DetachDisk
(
&
gcePersistentDiskCleaner
{
pd
}
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Warningf
(
"Failed to detach disk: %v (%v)"
,
pd
,
err
)
glog
.
Warningf
(
"Failed to detach disk: %v (%v)"
,
pd
,
err
)
}
}
}
}
type
gcePersistentDiskBuilder
struct
{
*
gcePersistentDisk
// Filesystem type, optional.
fsType
string
// Specifies whether the disk will be attached as read-only.
readOnly
bool
// diskMounter provides the interface that is used to mount the actual block device.
diskMounter
mount
.
Interface
}
var
_
volume
.
Builder
=
&
gcePersistentDiskBuilder
{}
// SetUp attaches the disk and bind mounts to the volume path.
// SetUp attaches the disk and bind mounts to the volume path.
func
(
pd
*
gcePersistentDisk
)
SetUp
()
error
{
func
(
b
*
gcePersistentDiskBuilder
)
SetUp
()
error
{
return
pd
.
SetUpAt
(
pd
.
GetPath
())
return
b
.
SetUpAt
(
b
.
GetPath
())
}
}
// SetUpAt attaches the disk and bind mounts to the volume path.
// SetUpAt attaches the disk and bind mounts to the volume path.
func
(
pd
*
gcePersistentDisk
)
SetUpAt
(
dir
string
)
error
{
func
(
b
*
gcePersistentDiskBuilder
)
SetUpAt
(
dir
string
)
error
{
// TODO: handle failed mounts here.
// TODO: handle failed mounts here.
mountpoint
,
err
:=
pd
.
mounter
.
IsMountPoint
(
dir
)
mountpoint
,
err
:=
b
.
mounter
.
IsMountPoint
(
dir
)
glog
.
V
(
4
)
.
Infof
(
"PersistentDisk set up: %s %v %v"
,
dir
,
mountpoint
,
err
)
glog
.
V
(
4
)
.
Infof
(
"PersistentDisk set up: %s %v %v"
,
dir
,
mountpoint
,
err
)
if
err
!=
nil
&&
!
os
.
IsNotExist
(
err
)
{
if
err
!=
nil
&&
!
os
.
IsNotExist
(
err
)
{
return
err
return
err
...
@@ -169,35 +175,35 @@ func (pd *gcePersistentDisk) SetUpAt(dir string) error {
...
@@ -169,35 +175,35 @@ func (pd *gcePersistentDisk) SetUpAt(dir string) error {
return
nil
return
nil
}
}
globalPDPath
:=
makeGlobalPDName
(
pd
.
plugin
.
host
,
pd
.
pdName
)
globalPDPath
:=
makeGlobalPDName
(
b
.
plugin
.
host
,
b
.
pdName
)
if
err
:=
pd
.
manager
.
AttachAndMountDisk
(
pd
,
globalPDPath
);
err
!=
nil
{
if
err
:=
b
.
manager
.
AttachAndMountDisk
(
b
,
globalPDPath
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
os
.
MkdirAll
(
dir
,
0750
);
err
!=
nil
{
if
err
:=
os
.
MkdirAll
(
dir
,
0750
);
err
!=
nil
{
// TODO: we should really eject the attach/detach out into its own control loop.
// TODO: we should really eject the attach/detach out into its own control loop.
detachDiskLogError
(
pd
)
detachDiskLogError
(
b
.
gcePersistentDisk
)
return
err
return
err
}
}
// Perform a bind mount to the full path to allow duplicate mounts of the same PD.
// Perform a bind mount to the full path to allow duplicate mounts of the same PD.
options
:=
[]
string
{
"bind"
}
options
:=
[]
string
{
"bind"
}
if
pd
.
readOnly
{
if
b
.
readOnly
{
options
=
append
(
options
,
"ro"
)
options
=
append
(
options
,
"ro"
)
}
}
err
=
pd
.
mounter
.
Mount
(
globalPDPath
,
dir
,
""
,
options
)
err
=
b
.
mounter
.
Mount
(
globalPDPath
,
dir
,
""
,
options
)
if
err
!=
nil
{
if
err
!=
nil
{
mountpoint
,
mntErr
:=
pd
.
mounter
.
IsMountPoint
(
dir
)
mountpoint
,
mntErr
:=
b
.
mounter
.
IsMountPoint
(
dir
)
if
mntErr
!=
nil
{
if
mntErr
!=
nil
{
glog
.
Errorf
(
"isMountpoint check failed: %v"
,
mntErr
)
glog
.
Errorf
(
"isMountpoint check failed: %v"
,
mntErr
)
return
err
return
err
}
}
if
mountpoint
{
if
mountpoint
{
if
mntErr
=
pd
.
mounter
.
Unmount
(
dir
);
mntErr
!=
nil
{
if
mntErr
=
b
.
mounter
.
Unmount
(
dir
);
mntErr
!=
nil
{
glog
.
Errorf
(
"Failed to unmount: %v"
,
mntErr
)
glog
.
Errorf
(
"Failed to unmount: %v"
,
mntErr
)
return
err
return
err
}
}
mountpoint
,
mntErr
:=
pd
.
mounter
.
IsMountPoint
(
dir
)
mountpoint
,
mntErr
:=
b
.
mounter
.
IsMountPoint
(
dir
)
if
mntErr
!=
nil
{
if
mntErr
!=
nil
{
glog
.
Errorf
(
"isMountpoint check failed: %v"
,
mntErr
)
glog
.
Errorf
(
"isMountpoint check failed: %v"
,
mntErr
)
return
err
return
err
...
@@ -210,7 +216,7 @@ func (pd *gcePersistentDisk) SetUpAt(dir string) error {
...
@@ -210,7 +216,7 @@ func (pd *gcePersistentDisk) SetUpAt(dir string) error {
}
}
os
.
Remove
(
dir
)
os
.
Remove
(
dir
)
// TODO: we should really eject the attach/detach out into its own control loop.
// TODO: we should really eject the attach/detach out into its own control loop.
detachDiskLogError
(
pd
)
detachDiskLogError
(
b
.
gcePersistentDisk
)
return
err
return
err
}
}
...
@@ -226,16 +232,22 @@ func (pd *gcePersistentDisk) GetPath() string {
...
@@ -226,16 +232,22 @@ func (pd *gcePersistentDisk) GetPath() string {
return
pd
.
plugin
.
host
.
GetPodVolumeDir
(
pd
.
podUID
,
util
.
EscapeQualifiedNameForDisk
(
name
),
pd
.
volName
)
return
pd
.
plugin
.
host
.
GetPodVolumeDir
(
pd
.
podUID
,
util
.
EscapeQualifiedNameForDisk
(
name
),
pd
.
volName
)
}
}
type
gcePersistentDiskCleaner
struct
{
*
gcePersistentDisk
}
var
_
volume
.
Cleaner
=
&
gcePersistentDiskCleaner
{}
// Unmounts the bind mount, and detaches the disk only if the PD
// Unmounts the bind mount, and detaches the disk only if the PD
// resource was the last reference to that disk on the kubelet.
// resource was the last reference to that disk on the kubelet.
func
(
pd
*
gcePersistentDisk
)
TearDown
()
error
{
func
(
c
*
gcePersistentDiskCleaner
)
TearDown
()
error
{
return
pd
.
TearDownAt
(
pd
.
GetPath
())
return
c
.
TearDownAt
(
c
.
GetPath
())
}
}
// Unmounts the bind mount, and detaches the disk only if the PD
// Unmounts the bind mount, and detaches the disk only if the PD
// resource was the last reference to that disk on the kubelet.
// resource was the last reference to that disk on the kubelet.
func
(
pd
*
gcePersistentDisk
)
TearDownAt
(
dir
string
)
error
{
func
(
c
*
gcePersistentDiskCleaner
)
TearDownAt
(
dir
string
)
error
{
mountpoint
,
err
:=
pd
.
mounter
.
IsMountPoint
(
dir
)
mountpoint
,
err
:=
c
.
mounter
.
IsMountPoint
(
dir
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -243,24 +255,24 @@ func (pd *gcePersistentDisk) TearDownAt(dir string) error {
...
@@ -243,24 +255,24 @@ func (pd *gcePersistentDisk) TearDownAt(dir string) error {
return
os
.
Remove
(
dir
)
return
os
.
Remove
(
dir
)
}
}
refs
,
err
:=
mount
.
GetMountRefs
(
pd
.
mounter
,
dir
)
refs
,
err
:=
mount
.
GetMountRefs
(
c
.
mounter
,
dir
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
// Unmount the bind-mount inside this pod
// Unmount the bind-mount inside this pod
if
err
:=
pd
.
mounter
.
Unmount
(
dir
);
err
!=
nil
{
if
err
:=
c
.
mounter
.
Unmount
(
dir
);
err
!=
nil
{
return
err
return
err
}
}
// If len(refs) is 1, then all bind mounts have been removed, and the
// If len(refs) is 1, then all bind mounts have been removed, and the
// remaining reference is the global mount. It is safe to detach.
// remaining reference is the global mount. It is safe to detach.
if
len
(
refs
)
==
1
{
if
len
(
refs
)
==
1
{
//
pd
.pdName is not initially set for volume-cleaners, so set it here.
//
c
.pdName is not initially set for volume-cleaners, so set it here.
pd
.
pdName
=
path
.
Base
(
refs
[
0
])
c
.
pdName
=
path
.
Base
(
refs
[
0
])
if
err
:=
pd
.
manager
.
DetachDisk
(
pd
);
err
!=
nil
{
if
err
:=
c
.
manager
.
DetachDisk
(
c
);
err
!=
nil
{
return
err
return
err
}
}
}
}
mountpoint
,
mntErr
:=
pd
.
mounter
.
IsMountPoint
(
dir
)
mountpoint
,
mntErr
:=
c
.
mounter
.
IsMountPoint
(
dir
)
if
mntErr
!=
nil
{
if
mntErr
!=
nil
{
glog
.
Errorf
(
"isMountpoint check failed: %v"
,
mntErr
)
glog
.
Errorf
(
"isMountpoint check failed: %v"
,
mntErr
)
return
err
return
err
...
...
pkg/volume/gce_pd/gce_pd_test.go
View file @
39a7fc37
...
@@ -74,8 +74,8 @@ type fakePDManager struct {
...
@@ -74,8 +74,8 @@ type fakePDManager struct {
// TODO(jonesdl) To fully test this, we could create a loopback device
// TODO(jonesdl) To fully test this, we could create a loopback device
// and mount that instead.
// and mount that instead.
func
(
fake
*
fakePDManager
)
AttachAndMountDisk
(
pd
*
gcePersistentDisk
,
globalPDPath
string
)
error
{
func
(
fake
*
fakePDManager
)
AttachAndMountDisk
(
b
*
gcePersistentDiskBuilder
,
globalPDPath
string
)
error
{
globalPath
:=
makeGlobalPDName
(
pd
.
plugin
.
host
,
pd
.
pdName
)
globalPath
:=
makeGlobalPDName
(
b
.
plugin
.
host
,
b
.
pdName
)
err
:=
os
.
MkdirAll
(
globalPath
,
0750
)
err
:=
os
.
MkdirAll
(
globalPath
,
0750
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -83,12 +83,12 @@ func (fake *fakePDManager) AttachAndMountDisk(pd *gcePersistentDisk, globalPDPat
...
@@ -83,12 +83,12 @@ func (fake *fakePDManager) AttachAndMountDisk(pd *gcePersistentDisk, globalPDPat
fake
.
attachCalled
=
true
fake
.
attachCalled
=
true
// Simulate the global mount so that the fakeMounter returns the
// Simulate the global mount so that the fakeMounter returns the
// expected number of mounts for the attached disk.
// expected number of mounts for the attached disk.
pd
.
mounter
.
Mount
(
globalPath
,
globalPath
,
pd
.
fsType
,
nil
)
b
.
mounter
.
Mount
(
globalPath
,
globalPath
,
b
.
fsType
,
nil
)
return
nil
return
nil
}
}
func
(
fake
*
fakePDManager
)
DetachDisk
(
pd
*
gcePersistentDisk
)
error
{
func
(
fake
*
fakePDManager
)
DetachDisk
(
c
*
gcePersistentDiskCleaner
)
error
{
globalPath
:=
makeGlobalPDName
(
pd
.
plugin
.
host
,
pd
.
pdName
)
globalPath
:=
makeGlobalPDName
(
c
.
plugin
.
host
,
c
.
pdName
)
err
:=
os
.
RemoveAll
(
globalPath
)
err
:=
os
.
RemoveAll
(
globalPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
...
pkg/volume/gce_pd/gce_util.go
View file @
39a7fc37
...
@@ -53,11 +53,11 @@ type GCEDiskUtil struct{}
...
@@ -53,11 +53,11 @@ type GCEDiskUtil struct{}
// Attaches a disk specified by a volume.GCEPersistentDisk to the current kubelet.
// Attaches a disk specified by a volume.GCEPersistentDisk to the current kubelet.
// Mounts the disk to it's global path.
// Mounts the disk to it's global path.
func
(
diskUtil
*
GCEDiskUtil
)
AttachAndMountDisk
(
pd
*
gcePersistentDisk
,
globalPDPath
string
)
error
{
func
(
diskUtil
*
GCEDiskUtil
)
AttachAndMountDisk
(
b
*
gcePersistentDiskBuilder
,
globalPDPath
string
)
error
{
glog
.
V
(
5
)
.
Infof
(
"AttachAndMountDisk(
pd, %q) where pd is %#v
\r\n
"
,
globalPDPath
,
pd
)
glog
.
V
(
5
)
.
Infof
(
"AttachAndMountDisk(
b, %q) where b is %#v
\r\n
"
,
globalPDPath
,
b
)
// Block execution until any pending detach goroutines for this pd have completed
// Block execution until any pending detach goroutines for this pd have completed
detachCleanupManager
.
Send
(
pd
.
pdName
,
true
)
detachCleanupManager
.
Send
(
b
.
pdName
,
true
)
sdBefore
,
err
:=
filepath
.
Glob
(
diskSDPattern
)
sdBefore
,
err
:=
filepath
.
Glob
(
diskSDPattern
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -65,13 +65,13 @@ func (diskUtil *GCEDiskUtil) AttachAndMountDisk(pd *gcePersistentDisk, globalPDP
...
@@ -65,13 +65,13 @@ func (diskUtil *GCEDiskUtil) AttachAndMountDisk(pd *gcePersistentDisk, globalPDP
}
}
sdBeforeSet
:=
util
.
NewStringSet
(
sdBefore
...
)
sdBeforeSet
:=
util
.
NewStringSet
(
sdBefore
...
)
devicePath
,
err
:=
attachDiskAndVerify
(
pd
,
sdBeforeSet
)
devicePath
,
err
:=
attachDiskAndVerify
(
b
,
sdBeforeSet
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
// Only mount the PD globally once.
// Only mount the PD globally once.
mountpoint
,
err
:=
pd
.
mounter
.
IsMountPoint
(
globalPDPath
)
mountpoint
,
err
:=
b
.
mounter
.
IsMountPoint
(
globalPDPath
)
if
err
!=
nil
{
if
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
if
os
.
IsNotExist
(
err
)
{
if
err
:=
os
.
MkdirAll
(
globalPDPath
,
0750
);
err
!=
nil
{
if
err
:=
os
.
MkdirAll
(
globalPDPath
,
0750
);
err
!=
nil
{
...
@@ -83,11 +83,11 @@ func (diskUtil *GCEDiskUtil) AttachAndMountDisk(pd *gcePersistentDisk, globalPDP
...
@@ -83,11 +83,11 @@ func (diskUtil *GCEDiskUtil) AttachAndMountDisk(pd *gcePersistentDisk, globalPDP
}
}
}
}
options
:=
[]
string
{}
options
:=
[]
string
{}
if
pd
.
readOnly
{
if
b
.
readOnly
{
options
=
append
(
options
,
"ro"
)
options
=
append
(
options
,
"ro"
)
}
}
if
!
mountpoint
{
if
!
mountpoint
{
err
=
pd
.
diskMounter
.
Mount
(
devicePath
,
globalPDPath
,
pd
.
fsType
,
options
)
err
=
b
.
diskMounter
.
Mount
(
devicePath
,
globalPDPath
,
b
.
fsType
,
options
)
if
err
!=
nil
{
if
err
!=
nil
{
os
.
Remove
(
globalPDPath
)
os
.
Remove
(
globalPDPath
)
return
err
return
err
...
@@ -97,32 +97,32 @@ func (diskUtil *GCEDiskUtil) AttachAndMountDisk(pd *gcePersistentDisk, globalPDP
...
@@ -97,32 +97,32 @@ func (diskUtil *GCEDiskUtil) AttachAndMountDisk(pd *gcePersistentDisk, globalPDP
}
}
// Unmounts the device and detaches the disk from the kubelet's host machine.
// Unmounts the device and detaches the disk from the kubelet's host machine.
func
(
util
*
GCEDiskUtil
)
DetachDisk
(
pd
*
gcePersistentDisk
)
error
{
func
(
util
*
GCEDiskUtil
)
DetachDisk
(
c
*
gcePersistentDiskCleaner
)
error
{
// Unmount the global PD mount, which should be the only one.
// Unmount the global PD mount, which should be the only one.
globalPDPath
:=
makeGlobalPDName
(
pd
.
plugin
.
host
,
pd
.
pdName
)
globalPDPath
:=
makeGlobalPDName
(
c
.
plugin
.
host
,
c
.
pdName
)
glog
.
V
(
5
)
.
Infof
(
"DetachDisk(
pd) where pd is %#v and the globalPDPath is %q
\r\n
"
,
pd
,
globalPDPath
)
glog
.
V
(
5
)
.
Infof
(
"DetachDisk(
c) where c is %#v and the globalPDPath is %q
\r\n
"
,
c
,
globalPDPath
)
if
err
:=
pd
.
mounter
.
Unmount
(
globalPDPath
);
err
!=
nil
{
if
err
:=
c
.
mounter
.
Unmount
(
globalPDPath
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
os
.
Remove
(
globalPDPath
);
err
!=
nil
{
if
err
:=
os
.
Remove
(
globalPDPath
);
err
!=
nil
{
return
err
return
err
}
}
if
detachCleanupManager
.
Exists
(
pd
.
pdName
)
{
if
detachCleanupManager
.
Exists
(
c
.
pdName
)
{
glog
.
Warningf
(
"Terminating new DetachDisk call for GCE PD %q. A previous detach call for this PD is still pending."
,
pd
.
pdName
)
glog
.
Warningf
(
"Terminating new DetachDisk call for GCE PD %q. A previous detach call for this PD is still pending."
,
c
.
pdName
)
return
nil
return
nil
}
}
// Detach disk, retry if needed.
// Detach disk, retry if needed.
go
detachDiskAndVerify
(
pd
)
go
detachDiskAndVerify
(
c
)
return
nil
return
nil
}
}
// Attaches the specified persistent disk device to node, verifies that it is attached, and retries if it fails.
// Attaches the specified persistent disk device to node, verifies that it is attached, and retries if it fails.
func
attachDiskAndVerify
(
pd
*
gcePersistentDisk
,
sdBeforeSet
util
.
StringSet
)
(
string
,
error
)
{
func
attachDiskAndVerify
(
b
*
gcePersistentDiskBuilder
,
sdBeforeSet
util
.
StringSet
)
(
string
,
error
)
{
devicePaths
:=
getDiskByIdPaths
(
pd
)
devicePaths
:=
getDiskByIdPaths
(
b
.
gcePersistentDisk
)
var
gce
cloudprovider
.
Interface
var
gce
cloudprovider
.
Interface
for
numRetries
:=
0
;
numRetries
<
maxRetries
;
numRetries
++
{
for
numRetries
:=
0
;
numRetries
<
maxRetries
;
numRetries
++
{
if
gce
==
nil
{
if
gce
==
nil
{
...
@@ -130,7 +130,7 @@ func attachDiskAndVerify(pd *gcePersistentDisk, sdBeforeSet util.StringSet) (str
...
@@ -130,7 +130,7 @@ func attachDiskAndVerify(pd *gcePersistentDisk, sdBeforeSet util.StringSet) (str
gce
,
err
=
cloudprovider
.
GetCloudProvider
(
"gce"
,
nil
)
gce
,
err
=
cloudprovider
.
GetCloudProvider
(
"gce"
,
nil
)
if
err
!=
nil
||
gce
==
nil
{
if
err
!=
nil
||
gce
==
nil
{
// Retry on error. See issue #11321
// Retry on error. See issue #11321
glog
.
Errorf
(
"Error getting GCECloudProvider while attaching PD %q: %v"
,
pd
.
pdName
,
err
)
glog
.
Errorf
(
"Error getting GCECloudProvider while attaching PD %q: %v"
,
b
.
pdName
,
err
)
gce
=
nil
gce
=
nil
time
.
Sleep
(
errorSleepDuration
)
time
.
Sleep
(
errorSleepDuration
)
continue
continue
...
@@ -138,13 +138,13 @@ func attachDiskAndVerify(pd *gcePersistentDisk, sdBeforeSet util.StringSet) (str
...
@@ -138,13 +138,13 @@ func attachDiskAndVerify(pd *gcePersistentDisk, sdBeforeSet util.StringSet) (str
}
}
if
numRetries
>
0
{
if
numRetries
>
0
{
glog
.
Warningf
(
"Timed out waiting for GCE PD %q to attach. Retrying attach."
,
pd
.
pdName
)
glog
.
Warningf
(
"Timed out waiting for GCE PD %q to attach. Retrying attach."
,
b
.
pdName
)
}
}
if
err
:=
gce
.
(
*
gce_cloud
.
GCECloud
)
.
AttachDisk
(
pd
.
pdName
,
pd
.
readOnly
);
err
!=
nil
{
if
err
:=
gce
.
(
*
gce_cloud
.
GCECloud
)
.
AttachDisk
(
b
.
pdName
,
b
.
readOnly
);
err
!=
nil
{
// Retry on error. See issue #11321. Continue and verify if disk is attached, because a
// Retry on error. See issue #11321. Continue and verify if disk is attached, because a
// previous attach operation may still succeed.
// previous attach operation may still succeed.
glog
.
Errorf
(
"Error attaching PD %q: %v"
,
pd
.
pdName
,
err
)
glog
.
Errorf
(
"Error attaching PD %q: %v"
,
b
.
pdName
,
err
)
}
}
for
numChecks
:=
0
;
numChecks
<
maxChecks
;
numChecks
++
{
for
numChecks
:=
0
;
numChecks
<
maxChecks
;
numChecks
++
{
...
@@ -159,51 +159,51 @@ func attachDiskAndVerify(pd *gcePersistentDisk, sdBeforeSet util.StringSet) (str
...
@@ -159,51 +159,51 @@ func attachDiskAndVerify(pd *gcePersistentDisk, sdBeforeSet util.StringSet) (str
glog
.
Errorf
(
"Error checking if path exists: %v"
,
err
)
glog
.
Errorf
(
"Error checking if path exists: %v"
,
err
)
}
else
if
pathExists
{
}
else
if
pathExists
{
// A device path has succesfully been created for the PD
// A device path has succesfully been created for the PD
glog
.
Infof
(
"Succesfully attached GCE PD %q."
,
pd
.
pdName
)
glog
.
Infof
(
"Succesfully attached GCE PD %q."
,
b
.
pdName
)
return
path
,
nil
return
path
,
nil
}
}
}
}
// Sleep then check again
// Sleep then check again
glog
.
V
(
3
)
.
Infof
(
"Waiting for GCE PD %q to attach."
,
pd
.
pdName
)
glog
.
V
(
3
)
.
Infof
(
"Waiting for GCE PD %q to attach."
,
b
.
pdName
)
time
.
Sleep
(
checkSleepDuration
)
time
.
Sleep
(
checkSleepDuration
)
}
}
}
}
return
""
,
fmt
.
Errorf
(
"Could not attach GCE PD %q. Timeout waiting for mount paths to be created."
,
pd
.
pdName
)
return
""
,
fmt
.
Errorf
(
"Could not attach GCE PD %q. Timeout waiting for mount paths to be created."
,
b
.
pdName
)
}
}
// Detaches the specified persistent disk device from node, verifies that it is detached, and retries if it fails.
// Detaches the specified persistent disk device from node, verifies that it is detached, and retries if it fails.
// This function is intended to be called asynchronously as a go routine.
// This function is intended to be called asynchronously as a go routine.
// It starts the detachCleanupManager with the specified pdName so that callers can wait for completion.
// It starts the detachCleanupManager with the specified pdName so that callers can wait for completion.
func
detachDiskAndVerify
(
pd
*
gcePersistentDisk
)
{
func
detachDiskAndVerify
(
c
*
gcePersistentDiskCleaner
)
{
glog
.
V
(
5
)
.
Infof
(
"detachDiskAndVerify for pd %q."
,
pd
.
pdName
)
glog
.
V
(
5
)
.
Infof
(
"detachDiskAndVerify for pd %q."
,
c
.
pdName
)
defer
util
.
HandleCrash
()
defer
util
.
HandleCrash
()
// Start operation, so that other threads can wait on this detach operation.
// Start operation, so that other threads can wait on this detach operation.
// Set bufferSize to 0 so senders are blocked on send until we recieve.
// Set bufferSize to 0 so senders are blocked on send until we recieve.
ch
,
err
:=
detachCleanupManager
.
Start
(
pd
.
pdName
,
0
/* bufferSize */
)
ch
,
err
:=
detachCleanupManager
.
Start
(
c
.
pdName
,
0
/* bufferSize */
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Error adding %q to detachCleanupManager: %v"
,
pd
.
pdName
,
err
)
glog
.
Errorf
(
"Error adding %q to detachCleanupManager: %v"
,
c
.
pdName
,
err
)
return
return
}
}
defer
detachCleanupManager
.
Close
(
pd
.
pdName
)
defer
detachCleanupManager
.
Close
(
c
.
pdName
)
defer
func
()
{
defer
func
()
{
// Unblock any callers that have been waiting for this detach routine to complete.
// Unblock any callers that have been waiting for this detach routine to complete.
for
{
for
{
select
{
select
{
case
<-
ch
:
case
<-
ch
:
glog
.
V
(
5
)
.
Infof
(
"detachDiskAndVerify for pd %q clearing chan."
,
pd
.
pdName
)
glog
.
V
(
5
)
.
Infof
(
"detachDiskAndVerify for pd %q clearing chan."
,
c
.
pdName
)
default
:
default
:
glog
.
V
(
5
)
.
Infof
(
"detachDiskAndVerify for pd %q done clearing chans."
,
pd
.
pdName
)
glog
.
V
(
5
)
.
Infof
(
"detachDiskAndVerify for pd %q done clearing chans."
,
c
.
pdName
)
return
return
}
}
}
}
}()
}()
devicePaths
:=
getDiskByIdPaths
(
pd
)
devicePaths
:=
getDiskByIdPaths
(
c
.
gcePersistentDisk
)
var
gce
cloudprovider
.
Interface
var
gce
cloudprovider
.
Interface
for
numRetries
:=
0
;
numRetries
<
maxRetries
;
numRetries
++
{
for
numRetries
:=
0
;
numRetries
<
maxRetries
;
numRetries
++
{
if
gce
==
nil
{
if
gce
==
nil
{
...
@@ -211,7 +211,7 @@ func detachDiskAndVerify(pd *gcePersistentDisk) {
...
@@ -211,7 +211,7 @@ func detachDiskAndVerify(pd *gcePersistentDisk) {
gce
,
err
=
cloudprovider
.
GetCloudProvider
(
"gce"
,
nil
)
gce
,
err
=
cloudprovider
.
GetCloudProvider
(
"gce"
,
nil
)
if
err
!=
nil
||
gce
==
nil
{
if
err
!=
nil
||
gce
==
nil
{
// Retry on error. See issue #11321
// Retry on error. See issue #11321
glog
.
Errorf
(
"Error getting GCECloudProvider while detaching PD %q: %v"
,
pd
.
pdName
,
err
)
glog
.
Errorf
(
"Error getting GCECloudProvider while detaching PD %q: %v"
,
c
.
pdName
,
err
)
gce
=
nil
gce
=
nil
time
.
Sleep
(
errorSleepDuration
)
time
.
Sleep
(
errorSleepDuration
)
continue
continue
...
@@ -219,13 +219,13 @@ func detachDiskAndVerify(pd *gcePersistentDisk) {
...
@@ -219,13 +219,13 @@ func detachDiskAndVerify(pd *gcePersistentDisk) {
}
}
if
numRetries
>
0
{
if
numRetries
>
0
{
glog
.
Warningf
(
"Timed out waiting for GCE PD %q to detach. Retrying detach."
,
pd
.
pdName
)
glog
.
Warningf
(
"Timed out waiting for GCE PD %q to detach. Retrying detach."
,
c
.
pdName
)
}
}
if
err
:=
gce
.
(
*
gce_cloud
.
GCECloud
)
.
DetachDisk
(
pd
.
pdName
);
err
!=
nil
{
if
err
:=
gce
.
(
*
gce_cloud
.
GCECloud
)
.
DetachDisk
(
c
.
pdName
);
err
!=
nil
{
// Retry on error. See issue #11321. Continue and verify if disk is detached, because a
// Retry on error. See issue #11321. Continue and verify if disk is detached, because a
// previous detach operation may still succeed.
// previous detach operation may still succeed.
glog
.
Errorf
(
"Error detaching PD %q: %v"
,
pd
.
pdName
,
err
)
glog
.
Errorf
(
"Error detaching PD %q: %v"
,
c
.
pdName
,
err
)
}
}
for
numChecks
:=
0
;
numChecks
<
maxChecks
;
numChecks
++
{
for
numChecks
:=
0
;
numChecks
<
maxChecks
;
numChecks
++
{
...
@@ -244,18 +244,18 @@ func detachDiskAndVerify(pd *gcePersistentDisk) {
...
@@ -244,18 +244,18 @@ func detachDiskAndVerify(pd *gcePersistentDisk) {
}
}
if
allPathsRemoved
{
if
allPathsRemoved
{
// All paths to the PD have been succefully removed
// All paths to the PD have been succefully removed
glog
.
Infof
(
"Succesfully detached GCE PD %q."
,
pd
.
pdName
)
glog
.
Infof
(
"Succesfully detached GCE PD %q."
,
c
.
pdName
)
return
return
}
}
// Sleep then check again
// Sleep then check again
glog
.
V
(
3
)
.
Infof
(
"Waiting for GCE PD %q to detach."
,
pd
.
pdName
)
glog
.
V
(
3
)
.
Infof
(
"Waiting for GCE PD %q to detach."
,
c
.
pdName
)
time
.
Sleep
(
checkSleepDuration
)
time
.
Sleep
(
checkSleepDuration
)
}
}
}
}
glog
.
Errorf
(
"Failed to detach GCE PD %q. One or more mount paths was not removed."
,
pd
.
pdName
)
glog
.
Errorf
(
"Failed to detach GCE PD %q. One or more mount paths was not removed."
,
c
.
pdName
)
}
}
// Returns list of all /dev/disk/by-id/* paths for given PD.
// Returns list of all /dev/disk/by-id/* paths for given PD.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment