Skip to content

Commit

Permalink
fix(resize): add rpc method to resize filesystem
Browse files Browse the repository at this point in the history
Signed-off-by: James Munson <james.munson@suse.com>
  • Loading branch information
james-munson committed Nov 7, 2024
1 parent 7cb78af commit b1f67dd
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 3 deletions.
11 changes: 10 additions & 1 deletion pkg/client/share_manager_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package client
import (
"context"

rpc "github.com/longhorn/types/pkg/generated/smrpc"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/protobuf/types/known/emptypb"

rpc "github.com/longhorn/types/pkg/generated/smrpc"

"github.com/longhorn/longhorn-share-manager/pkg/types"
)

Expand Down Expand Up @@ -47,6 +48,14 @@ func (c *ShareManagerClient) FilesystemTrim(encryptedDevice bool) error {
return err
}

func (c *ShareManagerClient) FilesystemResize() error {
ctx, cancel := context.WithTimeout(context.Background(), types.GRPCServiceTimeout)
defer cancel()

_, err := c.client.FilesystemResize(ctx, &emptypb.Empty{})
return err
}

func (c *ShareManagerClient) Unmount() error {
ctx, cancel := context.WithTimeout(context.Background(), types.GRPCServiceTimeout)
defer cancel()
Expand Down
18 changes: 18 additions & 0 deletions pkg/crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ func CloseVolume(volume string) error {
return err
}

func ResizeEncryptoDevice(volume, passphrase string) error {
devPath := types.GetVolumeDevicePath(volume, true)
if isOpen, err := IsDeviceOpen(devPath); err != nil {
return err
} else if !isOpen {
return fmt.Errorf("volume %v encrypto device is closed for resizing", volume)
}

namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc}
nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.HostProcDirectory, namespaces)
if err != nil {
return err
}

_, err = nsexec.LuksResize(volume, passphrase, lhtypes.LuksTimeout)
return err
}

// IsDeviceOpen determines if encrypted device is already open.
func IsDeviceOpen(device string) (bool, error) {
_, mappedFile, err := DeviceEncryptionStatus(device)
Expand Down
68 changes: 66 additions & 2 deletions pkg/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"time"

"github.com/google/fscrypt/filesystem"
lhexec "github.com/longhorn/go-common-libs/exec"
lhtypes "github.com/longhorn/go-common-libs/types"
"github.com/longhorn/types/pkg/generated/smrpc"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand All @@ -20,6 +18,10 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
"k8s.io/mount-utils"

lhexec "github.com/longhorn/go-common-libs/exec"
lhtypes "github.com/longhorn/go-common-libs/types"

"github.com/longhorn/longhorn-share-manager/pkg/crypto"
"github.com/longhorn/longhorn-share-manager/pkg/server"
"github.com/longhorn/longhorn-share-manager/pkg/server/nfs"
"github.com/longhorn/longhorn-share-manager/pkg/types"
Expand Down Expand Up @@ -114,6 +116,68 @@ func (s *ShareManagerServer) FilesystemTrim(ctx context.Context, req *smrpc.File
return &emptypb.Empty{}, nil
}

func (s *ShareManagerServer) FilesystemResize(ctx context.Context, req *emptypb.Empty) (resp *emptypb.Empty, err error) {
s.Lock()
defer s.Unlock()

vol := s.manager.GetVolume()
if vol.Name == "" {
s.logger.Warn("Volume name is missing")
return &emptypb.Empty{}, nil
}

log := s.logger.WithField("volume", vol.Name)

defer func() {
if err != nil {
log.WithError(err).Errorf("Failed to resize mounted filesystem on volume")
}
}()

devicePath := types.GetVolumeDevicePath(vol.Name, vol.IsEncrypted())
if !volume.CheckDeviceValid(devicePath) {
return &emptypb.Empty{}, grpcstatus.Errorf(grpccodes.FailedPrecondition, "volume %v is not valid", vol.Name)
}

mountPath := types.GetMountPath(vol.Name)
log = log.WithField("filesystem", mountPath)

_, err = filesystem.GetMount(mountPath)
if err != nil {
return &emptypb.Empty{}, grpcstatus.Error(grpccodes.Internal, err.Error())
}

log.Infof("Resizing mounted volume")

// TODO - should this go into volume.ResizeVolume so that the resize at server startup is encryption-aware?
if vol.IsEncrypted() {
diskFormat, err := volume.GetDiskFormat(devicePath)
if err != nil {
return &emptypb.Empty{}, grpcstatus.Errorf(grpccodes.Internal, "failed to determine disk format of volume %v: %v", vol.Name, err)
}
log.Infof("Device %v contains filesystem of format %v", devicePath, diskFormat)

if !strings.Contains(strings.ToLower(diskFormat), "luks") {
return &emptypb.Empty{}, grpcstatus.Errorf(grpccodes.InvalidArgument, "unsupported disk encryption format %v", diskFormat)
}

if err = crypto.ResizeEncryptoDevice(vol.Name, vol.Passphrase); err != nil {
return &emptypb.Empty{}, grpcstatus.Errorf(grpccodes.Internal, "failed to resize crypto device %v for volume %v node expansion: %v", devicePath, vol.Name, err)
}
}

if resized, err := volume.ResizeVolume(devicePath, mountPath); err != nil {
log.WithError(err).Errorf("Failed to resize filesystem")
return &emptypb.Empty{}, grpcstatus.Error(grpccodes.Internal, err.Error())
} else if resized {
log.Infof("Resized filesystem")
} else {
log.Infof("No resize needed for filesystem")
}

return &emptypb.Empty{}, nil
}

func (s *ShareManagerServer) unexport(vol volume.Volume) error {
exporter, err := nfs.NewExporter(configPath, types.ExportPath)
if err != nil {
Expand Down

0 comments on commit b1f67dd

Please sign in to comment.