mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-22 13:00:19 +00:00
cephfs: add helper for quiesce api
added helper function which calls the go-ceph API for the quiesce operations. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
parent
eff0fe3a23
commit
6a4c45deeb
250
internal/cephfs/core/quiesce.go
Normal file
250
internal/cephfs/core/quiesce.go
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
Copyright 2024 The Ceph-CSI Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ceph/ceph-csi/internal/util"
|
||||
"github.com/ceph/ceph-csi/internal/util/log"
|
||||
|
||||
"github.com/ceph/go-ceph/cephfs/admin"
|
||||
)
|
||||
|
||||
type QuiesceState string
|
||||
|
||||
const (
|
||||
Released QuiesceState = "RELEASED"
|
||||
Quiescing QuiesceState = "QUIESCING"
|
||||
Quiesced QuiesceState = "QUIESCED"
|
||||
)
|
||||
|
||||
// GetQuiesceState returns the quiesce state of the filesystem.
|
||||
func GetQuiesceState(set admin.QuiesceState) QuiesceState {
|
||||
var state QuiesceState
|
||||
switch set.Name {
|
||||
case "RELEASED":
|
||||
state = Released
|
||||
case "QUIESCING":
|
||||
state = Quiescing
|
||||
case "QUIESCED":
|
||||
state = Quiesced
|
||||
default:
|
||||
state = QuiesceState(set.Name)
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
type FSQuiesceClient interface {
|
||||
// Destroy destroys the connection used for FSAdmin.
|
||||
Destroy()
|
||||
// FSQuiesce quiesces the subvolumes in the filesystem.
|
||||
FSQuiesce(
|
||||
ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error)
|
||||
// GetVolumes returns the list of volumes in the filesystem that are to be
|
||||
// quiesced.
|
||||
GetVolumes() []Volume
|
||||
// FSQuiesceWithExpireTimeout quiesces the subvolumes in the filesystem
|
||||
// with an expiration timeout. it should be used after FSQuiesce to reset
|
||||
// the expire timeout. This helps in keeping the subvolumes in the
|
||||
// filesystem in quiesced state until all snapshots are taken.
|
||||
FSQuiesceWithExpireTimeout(ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error)
|
||||
// ResetFSQuiesce resets the quiesce timeout for the subvolumes in
|
||||
// the filesystem.
|
||||
ResetFSQuiesce(ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error)
|
||||
// ReleaseFSQuiesce releases the quiesce on the subvolumes in the
|
||||
// filesystem.
|
||||
ReleaseFSQuiesce(ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error)
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
VolumeID string
|
||||
ClusterID string
|
||||
}
|
||||
|
||||
type fsQuiesce struct {
|
||||
connection *util.ClusterConnection
|
||||
fsName string
|
||||
volumes []Volume
|
||||
// subVolumeGroupMapping is a map of subvolumes to groups.
|
||||
subVolumeGroupMapping map[string][]string
|
||||
fsa *admin.FSAdmin
|
||||
}
|
||||
|
||||
// NewFSQuiesce returns a new instance of fsQuiesce. It
|
||||
// take the filesystem name, the list of volumes to be quiesced, the mapping of
|
||||
// subvolumes to groups and the cluster connection as input.
|
||||
func NewFSQuiesce(
|
||||
fsName string,
|
||||
volumes []Volume,
|
||||
mapping map[string][]string,
|
||||
conn *util.ClusterConnection,
|
||||
) (FSQuiesceClient, error) {
|
||||
fsa, err := conn.GetFSAdmin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &fsQuiesce{
|
||||
connection: conn,
|
||||
fsName: fsName,
|
||||
volumes: volumes,
|
||||
subVolumeGroupMapping: mapping,
|
||||
fsa: fsa,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Destroy destroys the connection used for FSAdmin.
|
||||
func (fq *fsQuiesce) Destroy() {
|
||||
if fq.connection != nil {
|
||||
fq.connection.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
// GetVolumes returns the list of volumes in the filesystem that are to be
|
||||
// quiesced.
|
||||
func (fq *fsQuiesce) GetVolumes() []Volume {
|
||||
return fq.volumes
|
||||
}
|
||||
|
||||
// getMembers returns the list of names in the format
|
||||
// group/subvolume that are to be quiesced. This is the format that the
|
||||
// ceph fs quiesce expects.
|
||||
// Example: ["group1/subvolume1", "group1/subvolume2", "group2/subvolume1"].
|
||||
func (fq *fsQuiesce) getMembers() []string {
|
||||
volName := []string{}
|
||||
for svg, sb := range fq.subVolumeGroupMapping {
|
||||
for _, s := range sb {
|
||||
name := svg + "/" + s
|
||||
volName = append(volName, name)
|
||||
}
|
||||
}
|
||||
|
||||
return volName
|
||||
}
|
||||
|
||||
func (fq *fsQuiesce) FSQuiesce(
|
||||
ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error) {
|
||||
opt := &admin.FSQuiesceOptions{
|
||||
Timeout: 180,
|
||||
AwaitFor: 0,
|
||||
Expiration: 180,
|
||||
}
|
||||
log.DebugLog(ctx,
|
||||
"FSQuiesce for reserveName %s: members:%v options:%v",
|
||||
reserveName,
|
||||
fq.getMembers(),
|
||||
opt)
|
||||
resp, err := fq.fsa.FSQuiesce(fq.fsName, admin.NoGroup, fq.getMembers(), reserveName, opt)
|
||||
if resp != nil {
|
||||
qInfo := resp.Sets[reserveName]
|
||||
|
||||
return &qInfo, nil
|
||||
}
|
||||
|
||||
log.ErrorLog(ctx, "failed to quiesce filesystem %s", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (fq *fsQuiesce) FSQuiesceWithExpireTimeout(ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error) {
|
||||
opt := &admin.FSQuiesceOptions{
|
||||
Timeout: 180,
|
||||
AwaitFor: 0,
|
||||
Expiration: 180,
|
||||
}
|
||||
log.DebugLog(ctx,
|
||||
"FSQuiesceWithExpireTimeout for reserveName %s: members:%v options:%v",
|
||||
reserveName,
|
||||
fq.getMembers(),
|
||||
opt)
|
||||
resp, err := fq.fsa.FSQuiesce(fq.fsName, admin.NoGroup, fq.getMembers(), reserveName, opt)
|
||||
if resp != nil {
|
||||
qInfo := resp.Sets[reserveName]
|
||||
|
||||
return &qInfo, nil
|
||||
}
|
||||
|
||||
log.ErrorLog(ctx, "failed to quiesce filesystem with expire timeout %s", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (fq *fsQuiesce) ResetFSQuiesce(ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error) {
|
||||
opt := &admin.FSQuiesceOptions{
|
||||
Reset: true,
|
||||
AwaitFor: 0,
|
||||
Timeout: 180,
|
||||
Expiration: 180,
|
||||
}
|
||||
// Reset the filesystem quiesce so that the timer will be reset, and we can
|
||||
// reuse the same reservation if it has already failed or timed out.
|
||||
log.DebugLog(ctx,
|
||||
"ResetFSQuiesce for reserveName %s: members:%v options:%v",
|
||||
reserveName,
|
||||
fq.getMembers(),
|
||||
opt)
|
||||
resp, err := fq.fsa.FSQuiesce(fq.fsName, admin.NoGroup, fq.getMembers(), reserveName, opt)
|
||||
if resp != nil {
|
||||
qInfo := resp.Sets[reserveName]
|
||||
|
||||
return &qInfo, nil
|
||||
}
|
||||
|
||||
log.ErrorLog(ctx, "failed to reset timeout for quiesce filesystem %s", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (fq *fsQuiesce) ReleaseFSQuiesce(ctx context.Context,
|
||||
reserveName string,
|
||||
) (*admin.QuiesceInfo, error) {
|
||||
opt := &admin.FSQuiesceOptions{
|
||||
AwaitFor: 0,
|
||||
Release: true,
|
||||
}
|
||||
log.DebugLog(ctx,
|
||||
"ReleaseFSQuiesce for reserveName %s: members:%v options:%v",
|
||||
reserveName,
|
||||
fq.getMembers(),
|
||||
opt)
|
||||
resp, err := fq.fsa.FSQuiesce(fq.fsName, admin.NoGroup, []string{}, reserveName, opt)
|
||||
if resp != nil {
|
||||
qInfo := resp.Sets[reserveName]
|
||||
|
||||
return &qInfo, nil
|
||||
}
|
||||
|
||||
log.ErrorLog(ctx, "failed to release quiesce of filesystem %s", err)
|
||||
|
||||
return nil, err
|
||||
}
|
Loading…
Reference in New Issue
Block a user