Skip to content

Commit

Permalink
Tie the NFSv4.1 server into the virtual file system mounting code
Browse files Browse the repository at this point in the history
Add a 'minorVersion' configuration option that can be used to explicitly
choose between NFSv4.0 or NFSv4.1. Default to NFSv4.0, because that's
what macOS supports.
  • Loading branch information
EdSchouten committed Jul 9, 2024
1 parent 3a086e5 commit 226afa9
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 64 deletions.
80 changes: 65 additions & 15 deletions pkg/filesystem/virtual/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,18 @@ type nfsv4Mount struct {
}

func (m *nfsv4Mount) Expose(terminationGroup program.Group, rootDirectory virtual.Directory) error {
// Random values that the client can use to detect that the
// server has been restarted and lost all state.
var verifier nfsv4_xdr.Verifier4
random.FastThreadSafeGenerator.Read(verifier[:])
// Random values that the client can use to identify the server, or
// detect that the server has been restarted and lost all state.
var soMajorID [8]byte
random.FastThreadSafeGenerator.Read(soMajorID[:])
serverOwner := nfsv4_xdr.ServerOwner4{
SoMinorId: random.FastThreadSafeGenerator.Uint64(),
SoMajorId: soMajorID[:],
}
var serverScope [8]byte
random.FastThreadSafeGenerator.Read(serverScope[:])
var rebootVerifier nfsv4_xdr.Verifier4
random.FastThreadSafeGenerator.Read(rebootVerifier[:])
var stateIDOtherPrefix [4]byte
random.FastThreadSafeGenerator.Read(stateIDOtherPrefix[:])

Expand All @@ -60,22 +68,64 @@ func (m *nfsv4Mount) Expose(terminationGroup program.Group, rootDirectory virtua
return util.StatusWrap(err, "Invalid announced lease time")
}

var minorVersion uint32
if msg := m.configuration.MinorVersion; msg != nil {
minorVersion = msg.Value
} else {
var err error
minorVersion, err = getLatestSupportedNFSv4MinorVersion()
if err != nil {
return util.StatusWrap(err, "Unable to determine the latest minor version of NFSv4 supported by the operating system")
}
}

var program nfsv4_xdr.Nfs4Program
switch minorVersion {
case 0:
// Use NFSv4.0 (RFC 7530).
program = nfsv4.NewNFS40Program(
rootDirectory,
m.handleAllocator.ResolveHandle,
random.NewFastSingleThreadedGenerator(),
rebootVerifier,
stateIDOtherPrefix,
clock.SystemClock,
enforcedLeaseTime.AsDuration(),
announcedLeaseTime.AsDuration(),
)
case 1:
// Use NFSv4.1 (RFC 8881).
program = nfsv4.NewNFS41Program(
rootDirectory,
m.handleAllocator.ResolveHandle,
serverOwner,
serverScope[:],
// TODO: Should any of these parameters be configurable?
&nfsv4_xdr.ChannelAttrs4{
CaMaxrequestsize: 2 * 1024 * 1024,
CaMaxresponsesize: 2 * 1024 * 1024,
CaMaxresponsesizeCached: 64 * 1024,
CaMaxoperations: 1000,
CaMaxrequests: 100,
},
random.NewFastSingleThreadedGenerator(),
rebootVerifier,
clock.SystemClock,
enforcedLeaseTime.AsDuration(),
announcedLeaseTime.AsDuration(),
)
default:
return status.Errorf(codes.Unimplemented, "Unsupported NFSv4 minor version: %d", minorVersion)
}

// Create an RPC server that offers the NFSv4 program.
rpcServer := rpcserver.NewServer(map[uint32]rpcserver.Service{
nfsv4_xdr.NFS4_PROGRAM_PROGRAM_NUMBER: nfsv4_xdr.NewNfs4ProgramService(
nfsv4.NewMetricsProgram(
nfsv4.NewNFS40Program(
rootDirectory,
m.handleAllocator.ResolveHandle,
random.NewFastSingleThreadedGenerator(),
verifier,
stateIDOtherPrefix,
clock.SystemClock,
enforcedLeaseTime.AsDuration(),
announcedLeaseTime.AsDuration()))),
nfsv4.NewMetricsProgram(program),
),
}, m.authenticator)

return m.mount(terminationGroup, rpcServer)
return m.mount(terminationGroup, rpcServer, minorVersion)
}

// NewMountFromConfiguration creates a new FUSE mount based on options
Expand Down
11 changes: 8 additions & 3 deletions pkg/filesystem/virtual/configuration/nfsv4_mount_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ func (bv macOSBuildVersion) greaterEqual(major int64, minor byte, daily int64) b
return bv.major > major || (bv.major == major && (bv.minor > minor || (bv.minor == minor && bv.daily >= daily)))
}

func (m *nfsv4Mount) mount(terminationGroup program.Group, rpcServer *rpcserver.Server) error {
func getLatestSupportedNFSv4MinorVersion() (uint32, error) {
// macOS only supports NFSv4.0.
return 0, nil
}

func (m *nfsv4Mount) mount(terminationGroup program.Group, rpcServer *rpcserver.Server, minorVersion uint32) error {
// Extract the version of macOS used. We need to know this, as
// it determines which mount options are supported.
buildVersion, err := getMacOSBuildVersion()
Expand Down Expand Up @@ -159,11 +164,11 @@ func (m *nfsv4Mount) mount(terminationGroup program.Group, rpcServer *rpcserver.
}
flags.WriteTo(&attrVals)

// Explicitly request the use of NFSv4.0.
// Request the use of the desired NFSv4 protocol minor version.
attrMask[0] |= 1 << nfs_sys_prot.NFS_MATTR_NFS_VERSION
nfs_sys_prot.WriteNfsMattrNfsVersion(&attrVals, 4)
attrMask[0] |= 1 << nfs_sys_prot.NFS_MATTR_NFS_MINOR_VERSION
nfs_sys_prot.WriteNfsMattrNfsMinorVersion(&attrVals, 0)
nfs_sys_prot.WriteNfsMattrNfsMinorVersion(&attrVals, minorVersion)

// Set attribute caching durations. This needs to be set at
// mount time, as NFSv4 provides no facilities for conveying
Expand Down
6 changes: 5 additions & 1 deletion pkg/filesystem/virtual/configuration/nfsv4_mount_disabled.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
"google.golang.org/grpc/status"
)

func (m *nfsv4Mount) mount(terminationGroup program.Group, rpcServer *rpcserver.Server) error {
func getLatestSupportedNFSv4MinorVersion() (uint32, error) {
return 0, nil
}

func (m *nfsv4Mount) mount(terminationGroup program.Group, rpcServer *rpcserver.Server, minorVersion uint32) error {
return status.Error(codes.Unimplemented, "NFSv4 is not supported on this platform")
}
1 change: 1 addition & 0 deletions pkg/proto/configuration/filesystem/virtual/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ proto_library(
deps = [
"@com_github_buildbarn_bb_storage//pkg/proto/configuration/eviction:eviction_proto",
"@protobuf//:duration_proto",
"@protobuf//:wrappers_proto",
],
)

Expand Down
98 changes: 58 additions & 40 deletions pkg/proto/configuration/filesystem/virtual/virtual.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions pkg/proto/configuration/filesystem/virtual/virtual.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ syntax = "proto3";
package buildbarn.configuration.filesystem.virtual;

import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "pkg/proto/configuration/eviction/eviction.proto";

option go_package = "github.com/buildbarn/bb-remote-execution/pkg/proto/configuration/filesystem/virtual";
Expand All @@ -24,11 +25,6 @@ message MountConfiguration {
// to expose the mount. This option is supported on macOS starting
// with Ventura 13.3 (22E252), though the use of Sonoma 14.5
// (23F79) or later is strongly recommended.
//
// The NFS server is expected to conform to NFSv4.0 (RFC 7530).
// Features provided by newer versions of the protocol, such as
// NFSv4.1 (RFC 8881) and NFSv4.2 (RFC 7862), are not supported at
// this time. macOS also does not support the latter.
NFSv4MountConfiguration nfsv4 = 3;
}
}
Expand Down Expand Up @@ -170,6 +166,18 @@ message NFSv4MountConfiguration {
//
// NOTE: This option is only used by bb_virtual_tmp.
RPCv2SystemAuthenticationConfiguration system_authentication = 4;

// The minor version of the protocol to use.
//
// When set to 0, the NFS server is expected to conform to NFSv4.0
// (RFC 7530). When set to 1, the NFS server is expected to conform to
// NFSv4.1 (RFC 8881). The use of NFSv4.1 is recommended, because it
// provides better parallelism.
//
// When left unset, the latest protocol version is used that is
// supported by the currently running operating system. In the case of
// macOS, this is NFSv4.0.
google.protobuf.UInt32Value minor_version = 5;
}

message NFSv4DarwinMountConfiguration {
Expand Down

0 comments on commit 226afa9

Please sign in to comment.