Skip to content

Commit 44d6f81

Browse files
authored
Fix NFS VolumeStore FQDN not working (#8244)
* Fix NFS VolumeStore FQDN not working When docker using a nfs VolumeStore as a volume, the mount action will fail if the nfs-server url is a FQDN. A dotted ip url works well. When the linux syscall mount(source, target, flag, mountOptions) using for nfs mount, its mountOptions should contain 'addr=serverip' and the serverip must be an ip(ps. the url in source is useless). Thus the fix resolve the FQDN and give its mountOptions the 'addr=ip'. The mountOptions is generated as 'addr=host' at CreateMountSpec when creating the endpointVM. The fix choose to do the resolve just before the mounting action. Resolve: #8043
1 parent b0e1466 commit 44d6f81

3 files changed

Lines changed: 37 additions & 6 deletions

File tree

lib/tether/ops_linux.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -960,14 +960,25 @@ func (t *BaseOperations) MountTarget(ctx context.Context, source url.URL, target
960960
}
961961
rawSource.WriteString(source.Path)
962962

963-
// NOTE: by default we are supporting "NOATIME" and it can be configurable later. this must be specfied as a flag.
964-
// Additionally, we must parse out the "ro" option and supply it as a flag as well for this flavor of the mount call.
965-
if err := Sys.Syscall.Mount(rawSource.String(), target, nfsFileSystemType, syscall.MS_NOATIME, mountOptions); err != nil {
966-
log.Errorf("mounting %s on %s failed: %s", source.String(), target, err)
963+
ips, err := net.LookupIP(source.Hostname())
964+
if err != nil {
965+
log.Errorf("failing to resolve %s. mounting %s on %s failed: %s", source.Hostname(), source.String(), target, err)
967966
return err
968967
}
969-
970-
return nil
968+
for _, ip := range ips {
969+
//NOTE: the mountOptions of syscall mount only accept addr=ip. addr=FQDN doesn't work
970+
//We resolve the ip address nearest the mounting action.
971+
mountOptionsIP := strings.Replace(mountOptions, "addr="+source.Hostname(), "addr="+ip.String(), -1)
972+
// NOTE: by default we are supporting "NOATIME" and it can be configurable later. this must be specfied as a flag.
973+
// Additionally, we must parse out the "ro" option and supply it as a flag as well for this flavor of the mount call.
974+
if err = Sys.Syscall.Mount(rawSource.String(), target, nfsFileSystemType, syscall.MS_NOATIME, mountOptionsIP); err != nil {
975+
log.Debugf("mounting %s with resolved ip: %s on %s failed: %s", source.String(), ip.String(), target, err)
976+
} else {
977+
return nil
978+
}
979+
}
980+
log.Errorf("mounting %s on %s failed: %s", source.String(), target, err)
981+
return err
971982
}
972983

973984
// CopyExistingContent copies the underlying files shadowed by a mount on a directory

tests/test-cases/Group1-Docker-Commands/1-19-Docker-Volume-Create.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This test requires that a vSphere server is running and available
2929
15. Create container with a named volume and verify that base image files are copied to the named volume
3030
16. Create container with a named volume. Modify the copied image file. Remount the volume in a new container.
3131
17. Run container with a volume, and run another container with same volume
32+
18. Create a nfs server, get its fqdn and add a fqdn-based nfs VolumeStore to VCH, and run a container to mount the volume of this VolumeStore.
3233

3334
# Expected Outcome:
3435
* Steps 2 and 3 should complete successfully and return the name of the volume created, you should then be able to see the volume has been created
@@ -58,6 +59,7 @@ Error response from daemon: create test???: "test???" includes invalid character
5859
* Step 15 should result in success and print data in the volume
5960
* Step 16 should result in success and the second container should contain the modified file contents
6061
* Step 17 should result in error with message `devices <volume id> in use`
62+
* Step 18 should result in success and print data in the volume
6163

6264
# Possible Problems:
6365
* VIC requires you to specify storage on creation of the VCH that volumes can be created from, so when installing the VCH make sure to specify this parameter: --volume-store=

tests/test-cases/Group1-Docker-Commands/1-19-Docker-Volume-Create.robot

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,21 @@ Docker volume conflict in new container
217217
Should Be Equal As Integers ${rc} 125
218218
Should Contain ${output} Error response from daemon
219219
Should Contain ${output} device ${volID} in use
220+
221+
Docker volume create fqdn-based nfs datastore
222+
${rc} ${output}= Run And Return Rc And Output docker %{VCH-PARAMS} volume create --name nfs-vol --opt Capacity=5G
223+
Should Be Equal As Integers ${rc} 0
224+
${rc} ${output}= Run And Return Rc And Output docker %{VCH-PARAMS} run -d -v nfs-vol:/mnt/nfs-vol --net public --name nfs-server -p 111:111 -p 2049:2049 -p 32767:32767 -p 32768:32768 -e EXPORT_FOLDER=/mnt/nfs-vol bensdoings/nfs-server
225+
Should Be Equal As Integers ${rc} 0
226+
${ip}= Get Container IP %{VCH-PARAMS} nfs-server public
227+
${rc} ${fqdn}= Run And Return Rc And Output docker %{VCH-PARAMS} run --net public ${busybox} nslookup ${ip} | awk -F'${ip} ' '/${ip} /{print $2}'
228+
Should Be Equal As Integers ${rc} 0
229+
${output}= Run bin/vic-machine-linux configure --name=%{VCH-NAME} --target=%{TEST_URL} --thumbprint=%{TEST_THUMBPRINT} --user=%{TEST_USERNAME} --password=%{TEST_PASSWORD} --timeout %{TEST_TIMEOUT} --volume-store=%{TEST_DATASTORE}/%{VCH-NAME}-VOL:default --volume-store=\'nfs://${fqdn}/mnt/nfs-vol?uid=0&gid=0&proto=tcp&port=2049:nfsfqdn\'
230+
Should Contain ${output} Completed successfully
231+
${rc} ${output}= Run And Return Rc And Output docker %{VCH-PARAMS} volume create --name nfs-vol-fqdn --opt VolumeStore=nfsfqdn
232+
Should Be Equal As Integers ${rc} 0
233+
${rc} ${output}= Run And Return Rc And Output docker %{VCH-PARAMS} run -v nfs-vol-fqdn:/data ${busybox} sh -c "echo fqdn > /data/fqdn"
234+
Should Be Equal As Integers ${rc} 0
235+
${rc} ${output}= Run And Return Rc And Output docker %{VCH-PARAMS} run -v nfs-vol-fqdn:/data ${busybox} sh -c "cat /data/fqdn"
236+
Should Be Equal As Integers ${rc} 0
237+
Should Contain ${output} fqdn

0 commit comments

Comments
 (0)