fix(region,host): mount fusefs on guest start

In case of host shutdown, fusefs will not mount on host reboot.
Add check and mount fusefs on guest start.

Signed-off-by: wanyaoqi <d3lx.yq@gmail.com>
This commit is contained in:
wanyaoqi
2022-08-01 10:28:57 +08:00
committed by wanyaoqi
parent 597adce302
commit b96721fc58
7 changed files with 95 additions and 12 deletions
+9
View File
@@ -722,6 +722,15 @@ func (self *SDisk) StartDiskCreateTask(ctx context.Context, userCred mcclient.To
return nil
}
func (self *SDisk) GetSnapshotFuseUrl() (string, error) {
snapObj, err := SnapshotManager.FetchById(self.SnapshotId)
if err != nil {
return "", errors.Wrapf(err, "SnapshotManager.FetchById(%s)", self.SnapshotId)
}
snapshot := snapObj.(*SSnapshot)
return snapshot.GetFuseUrl()
}
func (self *SDisk) GetSnapshotCount() (int, error) {
q := SnapshotManager.Query()
return q.Filter(sqlchemy.AND(sqlchemy.Equals(q.Field("disk_id"), self.Id),
+7
View File
@@ -211,6 +211,13 @@ func (self *SGuestdisk) GetJsonDescAtHost(ctx context.Context, host *SHost) *api
if needMerge == "true" {
desc.MergeSnapshot = true
}
if desc.MergeSnapshot {
if url, err := disk.GetSnapshotFuseUrl(); err != nil {
log.Errorf("failed get snapshot fuse url: %s", err)
} else {
desc.Url = url
}
}
}
if fpath := disk.GetMetadata(ctx, api.DISK_META_ESXI_FLAT_FILE_PATH, nil); len(fpath) > 0 {
desc.MergeSnapshot = true
+16
View File
@@ -490,6 +490,22 @@ func (self *SSnapshot) GetHost() (*SHost, error) {
return storage.GetMasterHost()
}
func (self *SSnapshot) GetFuseUrl() (string, error) {
iStorage, err := StorageManager.FetchById(self.StorageId)
if err != nil {
return "", errors.Wrapf(err, "StorageManager.FetchById(%s)", self.StorageId)
}
storage := iStorage.(*SStorage)
if storage.StorageType != api.STORAGE_LOCAL {
return "", nil
}
host, err := storage.GetMasterHost()
if err != nil {
return "", err
}
return fmt.Sprintf("%s/snapshots/%s/%s", host.GetFetchUrl(true), self.DiskId, self.Id), nil
}
func (self *SSnapshotManager) AddRefCount(snapshotId string, count int) {
iSnapshot, _ := self.FetchById(snapshotId)
if iSnapshot != nil {
+7 -6
View File
@@ -746,13 +746,14 @@ func (m *SGuestManager) GuestStart(ctx context.Context, userCred mcclient.TokenC
guest.SaveDesc(guestDesc)
}
if guest.IsStopped() {
data := struct {
Params *jsonutils.JSONDict
}{
Params: jsonutils.NewDict(),
data, err := body.Get("params")
if err != nil {
data = jsonutils.NewDict()
}
err = guest.StartGuest(ctx, userCred, data.(*jsonutils.JSONDict))
if err != nil {
return nil, err
}
body.Unmarshal(&data)
guest.StartGuest(ctx, userCred, data.Params)
res := jsonutils.NewDict()
res.Set("vnc_port", jsonutils.NewInt(0))
return res, nil
+48 -5
View File
@@ -57,6 +57,7 @@ import (
identity_modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
"yunion.io/x/onecloud/pkg/util/cgrouputils"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/fuseutils"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/procutils"
"yunion.io/x/onecloud/pkg/util/qemuimg"
@@ -323,17 +324,56 @@ func (s *SKVMGuestInstance) DirtyServerRequestStart() {
}
}
func (s *SKVMGuestInstance) fuseMount(encryptInfo *apis.SEncryptInfo) error {
disks := s.Desc.Disks
for i := 0; i < len(disks); i++ {
if disks[i].MergeSnapshot && len(disks[i].Url) > 0 {
disk, err := storageman.GetManager().GetDiskByPath(disks[i].Path)
if err != nil {
return errors.Wrapf(err, "GetDiskByPath(%s)", disks[i].Path)
}
storage := disk.GetStorage()
mntPath := path.Join(storage.GetFuseMountPath(), disk.GetId())
if err := procutils.NewCommand("mountpoint", mntPath).Run(); err == nil {
// fetcherfs is mounted
continue
}
tmpdir := storage.GetFuseTmpPath()
err = fuseutils.MountFusefs(
options.HostOptions.FetcherfsPath, disks[i].Url, tmpdir,
auth.GetTokenString(), mntPath,
options.HostOptions.FetcherfsBlockSize,
encryptInfo,
)
if err != nil {
return err
}
}
}
return nil
}
func (s *SKVMGuestInstance) asyncScriptStart(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
data, ok := params.(*jsonutils.JSONDict)
if !ok {
return nil, hostutils.ParamsError
}
hostbridge.CleanDeletedPorts(options.HostOptions.BridgeDriver)
time.Sleep(100 * time.Millisecond)
var isStarted, tried = false, 0
var err error
var encryptInfo *apis.SEncryptInfo
if data.Contains("encrypt_info") {
encryptInfo = new(apis.SEncryptInfo)
data.Unmarshal(encryptInfo, "encrypt_info")
}
err = s.fuseMount(encryptInfo)
if err != nil {
return nil, errors.Wrap(err, "fuse mount")
}
hostbridge.CleanDeletedPorts(options.HostOptions.BridgeDriver)
time.Sleep(100 * time.Millisecond)
var isStarted, tried = false, 0
for !isStarted && tried < MAX_TRY {
tried += 1
@@ -433,7 +473,9 @@ func (s *SKVMGuestInstance) ImportServer(pendingDelete bool) {
if (s.IsDirtyShotdown() || s.IsDaemon()) && !pendingDelete {
log.Infof("Server dirty shutdown or a daemon %s", s.GetName())
if s.Desc.IsMaster || s.Desc.IsSlave {
if s.Desc.IsMaster || s.Desc.IsSlave ||
len(s.GetNeedMergeBackingFileDiskIndexs()) > 0 {
go s.DirtyServerRequestStart()
} else {
s.StartGuest(context.Background(), nil, jsonutils.NewDict())
@@ -1091,6 +1133,7 @@ func (s *SKVMGuestInstance) prepareEncryptKeyForStart(ctx context.Context, userC
params = jsonutils.NewDict()
}
params.Add(jsonutils.NewString(ekey.Key), "encrypt_key")
params.Add(jsonutils.Marshal(ekey), "encrypt_info")
}
return params, nil
}
+3 -1
View File
@@ -234,7 +234,9 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
if data.Contains("encrypt_key") {
key, _ := data.GetString("encrypt_key")
s.saveEncryptKeyFile(key)
if err := s.saveEncryptKeyFile(key); err != nil {
return "", errors.Wrap(err, "save encrypt key file")
}
input.EncryptKeyPath = s.getEncryptKeyPath()
}
+5
View File
@@ -44,6 +44,7 @@ type IDisk interface {
GetSnapshotLocation() string
OnRebuildRoot(ctx context.Context, params api.DiskAllocateInput) error
DoDeleteSnapshot(snapshotId string) error
GetStorage() IStorage
DeleteAllSnapshot(skipRecycle bool) error
DiskSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
@@ -90,6 +91,10 @@ func (d *SBaseDisk) GetId() string {
return d.Id
}
func (d *SBaseDisk) GetStorage() IStorage {
return d.Storage
}
func (d *SBaseDisk) GetPath() string {
return path.Join(d.Storage.GetPath(), d.Id)
}