Skip to content

Commit d804dfb

Browse files
committed
logic to find device for xenserver and update dockerfile to include udevadm in PATH
1 parent 7fe3d59 commit d804dfb

File tree

3 files changed

+109
-5
lines changed

3 files changed

+109
-5
lines changed

cmd/cloudstack-csi-driver/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ RUN apk add --no-cache \
1414
# blkid, mount and umount are required by k8s.io/mount-utils \
1515
blkid \
1616
mount \
17-
umount
17+
umount \
18+
# Provides udevadm for device management
19+
udev
1820

1921
COPY ./bin/cloudstack-csi-driver /cloudstack-csi-driver
2022
ENTRYPOINT ["/cloudstack-csi-driver"]

deploy/k8s/node-daemonset.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ spec:
6464
mountPath: /dev
6565
- name: cloud-init-dir
6666
mountPath: /run/cloud-init/
67+
- name: sys-dir
68+
mountPath: /sys
6769
# Comment the above 2 lines and uncomment the next 2 lines for Ignition support
6870
# - name: ignition-dir
6971
# mountPath: /run/metadata
@@ -177,6 +179,10 @@ spec:
177179
hostPath:
178180
path: /run/cloud-init/
179181
type: Directory
182+
- name: sys-dir
183+
hostPath:
184+
path: /sys
185+
type: Directory
180186
# Comment the above 4 lines and uncomment the next 4 lines for Ignition support
181187
# - name: ignition-dir
182188
# hostPath:

pkg/mount/mount.go

Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,26 +114,122 @@ func (m *mounter) GetDevicePath(ctx context.Context, volumeID string) (string, e
114114
}
115115

116116
func (m *mounter) getDevicePathBySerialID(volumeID string) (string, error) {
117+
// First try XenServer device paths
118+
for i := 'b'; i <= 'z'; i++ {
119+
devicePath := fmt.Sprintf("/dev/xvd%c", i)
120+
fmt.Printf("Checking XenServer device path: %s\n", devicePath)
121+
122+
if _, err := os.Stat(devicePath); err == nil {
123+
isBlock, err := m.IsBlockDevice(devicePath)
124+
if err == nil && isBlock {
125+
if m.verifyXenServerDevice(devicePath, volumeID) {
126+
fmt.Printf("Found and verified XenServer device: %s\n", devicePath)
127+
return devicePath, nil
128+
}
129+
}
130+
}
131+
}
132+
133+
// Fall back to standard device paths
117134
sourcePathPrefixes := []string{"virtio-", "scsi-", "scsi-0QEMU_QEMU_HARDDISK_"}
118135
serial := diskUUIDToSerial(volumeID)
119-
fmt.Println("Searching for device with serial: %s", serial)
136+
fmt.Printf("Searching for device with serial: %s\n", serial)
120137
for _, prefix := range sourcePathPrefixes {
121138
source := filepath.Join(diskIDPath, prefix+serial)
122-
fmt.Println("source", source)
123-
fmt.Println("Checking path: %s", source)
139+
fmt.Printf("Checking path: %s\n", source)
124140
_, err := os.Stat(source)
125141
if err == nil {
126142
return source, nil
127143
}
128144
if !os.IsNotExist(err) {
129-
fmt.Println("Not found: %s", err.Error())
145+
fmt.Printf("Not found: %s\n", err.Error())
130146
return "", err
131147
}
132148
}
133149

134150
return "", nil
135151
}
136152

153+
func (m *mounter) verifyXenServerDevice(devicePath string, volumeID string) bool {
154+
size, err := m.GetBlockSizeBytes(devicePath)
155+
if err != nil {
156+
fmt.Printf("Failed to get device size: %v\n", err)
157+
return false
158+
}
159+
fmt.Printf("Device size: %d bytes\n", size)
160+
161+
mounted, err := m.isDeviceMounted(devicePath)
162+
if err != nil {
163+
fmt.Printf("Failed to check if device is mounted: %v\n", err)
164+
return false
165+
}
166+
if mounted {
167+
fmt.Printf("Device is already mounted: %s\n", devicePath)
168+
return false
169+
}
170+
171+
inUse, err := m.isDeviceInUse(devicePath)
172+
if err != nil {
173+
fmt.Printf("Failed to check if device is in use: %v\n", err)
174+
return false
175+
}
176+
if inUse {
177+
fmt.Printf("Device is in use: %s\n", devicePath)
178+
return false
179+
}
180+
181+
props, err := m.getDeviceProperties(devicePath)
182+
if err != nil {
183+
fmt.Printf("Failed to get device properties: %v\n", err)
184+
return false
185+
}
186+
fmt.Printf("Device properties: %v\n", props)
187+
188+
return true
189+
}
190+
191+
func (m *mounter) isDeviceMounted(devicePath string) (bool, error) {
192+
output, err := m.Exec.Command("grep", devicePath, "/proc/mounts").Output()
193+
if err != nil {
194+
if strings.Contains(err.Error(), "exit status 1") {
195+
return false, nil
196+
}
197+
return false, err
198+
}
199+
return len(output) > 0, nil
200+
}
201+
202+
func (m *mounter) isDeviceInUse(devicePath string) (bool, error) {
203+
output, err := m.Exec.Command("lsof", devicePath).Output()
204+
if err != nil {
205+
if strings.Contains(err.Error(), "exit status 1") {
206+
return false, nil
207+
}
208+
return false, err
209+
}
210+
return len(output) > 0, nil
211+
}
212+
213+
func (m *mounter) getDeviceProperties(devicePath string) (map[string]string, error) {
214+
output, err := m.Exec.Command("udevadm", "info", "--query=property", devicePath).Output()
215+
if err != nil {
216+
return nil, err
217+
}
218+
219+
props := make(map[string]string)
220+
for _, line := range strings.Split(string(output), "\n") {
221+
if line == "" {
222+
continue
223+
}
224+
parts := strings.Split(line, "=")
225+
if len(parts) == 2 {
226+
props[parts[0]] = parts[1]
227+
}
228+
}
229+
230+
return props, nil
231+
}
232+
137233
func (m *mounter) probeVolume(ctx context.Context) {
138234
logger := klog.FromContext(ctx)
139235
logger.V(2).Info("Scanning SCSI host")

0 commit comments

Comments
 (0)