mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-13 07:46:56 +08:00
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:
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user