Merge pull request #6621 from wanyaoqi/bugfix/wyq/host-storage-misc-fix

host storage misc fix:
This commit is contained in:
Zexi Li
2020-05-27 18:03:47 +08:00
committed by GitHub
8 changed files with 106 additions and 15 deletions
+14
View File
@@ -234,6 +234,20 @@ func init() {
return nil
})
type StorageForceDetachHost struct {
ID string `help:"ID or name of storage" json:"-"`
Host string `help:"ID or name of host"`
}
R(&StorageForceDetachHost{}, "storage-public", "Force detach host", func(s *mcclient.ClientSession, args *StorageForceDetachHost) error {
params := jsonutils.Marshal(args)
result, err := modules.Storages.PerformAction(s, args.ID, "force-detach-host", params)
if err != nil {
return err
}
printObject(result)
return nil
})
type StoragePublicOptions struct {
ID string `help:"ID or name of storage" json:"-"`
Scope string `help:"sharing scope" choices:"system|domain"`
+5
View File
@@ -224,6 +224,11 @@ type PerformEnableInput struct {
type PerformDisableInput struct {
}
type StorageForceDetachHostInput struct {
// Host id or name
Host string `json:"host"`
}
type InfrasResourceBaseCreateInput struct {
DomainLevelResourceCreateInput
+33
View File
@@ -1549,3 +1549,36 @@ func (manager *SStorageManager) ListItemExportKeys(ctx context.Context,
}
return q, nil
}
func (storage *SStorage) AllowPerformForceDetachHost(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, storage, "force-detach-host")
}
func (storage *SStorage) PerformForceDetachHost(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.StorageForceDetachHostInput) (jsonutils.JSONObject, error) {
if storage.Enabled.Bool() {
return nil, httperrors.NewBadRequestError("storage is enabled")
}
iHost, err := HostManager.FetchByIdOrName(userCred, input.Host)
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("host %s not found", input.Host)
} else if err != nil {
return nil, err
}
host := iHost.(*SHost)
if host.Status == api.HOST_ONLINE {
return nil, httperrors.NewBadRequestError("can't detach host in status online")
}
iHostStorage, err := db.FetchJointByIds(HoststorageManager, host.GetId(), storage.Id, nil)
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("host %s storage %s not found", input.Host, storage.Name)
} else if err != nil {
return nil, err
}
hostStorage := iHostStorage.(*SHoststorage)
hostStorage.SetModelManager(HoststorageManager, hostStorage)
err = hostStorage.Delete(ctx, userCred)
if err == nil {
db.OpsLog.LogDetachEvent(ctx, hostStorage.Master(), hostStorage.Slave(), userCred, jsonutils.NewString("force detach"))
}
return nil, err
}
+3
View File
@@ -1261,6 +1261,9 @@ func (h *SHostInfo) onGetStorageInfoSucc(hoststorages []jsonutils.JSONObject) {
storage.SetStoragecacheId(storagecacheId)
storage.SetStorageInfo(storageId, storageName, storageConf)
storageManager.Storages = append(storageManager.Storages, storage)
if err := storage.Accessible(); err != nil {
h.onFail(err)
}
storageManager.InitSharedStorageImageCache(
storagetype, storagecacheId, imagecachePath, storage)
}
+3 -1
View File
@@ -65,12 +65,14 @@ func NewStorageManager(host hostutils.IHost) (*SStorageManager, error) {
for i, d := range options.HostOptions.LocalImagePath {
s := NewLocalStorage(ret, d, i)
if s.Accessible() {
if err := s.Accessible(); err == nil {
StartSnapshotRecycle(s)
ret.Storages = append(ret.Storages, s)
if allFull && s.GetFreeSizeMb() > MINIMAL_FREE_SPACE {
allFull = false
}
} else {
log.Errorf("storage %s not accessible", s.Path)
}
}
+8
View File
@@ -43,8 +43,14 @@ const (
_RECYCLE_BIN_ = "recycle_bin"
_IMGSAVE_BACKUPS_ = "imgsave_backups"
_SNAPSHOT_PATH_ = "snapshots"
ErrStorageTimeout = constError("storage accessible check timeout")
)
type constError string
func (e constError) Error() string { return string(e) }
var DELETEING_SNAPSHOTS = sync.Map{}
type IStorageFactory interface {
@@ -115,6 +121,8 @@ type IStorage interface {
DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool) error
Accessible() error
}
type SBaseStorage struct {
+24 -9
View File
@@ -146,17 +146,32 @@ func (s *SLocalStorage) CreateDisk(diskId string) IDisk {
return disk
}
func (s *SLocalStorage) Accessible() bool {
if !fileutils2.Exists(s.Path) {
if err := procutils.NewCommand("mkdir", "-p", s.Path).Run(); err != nil {
log.Errorln(err)
func (s *SLocalStorage) Accessible() error {
var c = make(chan error)
go func() {
if !fileutils2.Exists(s.Path) {
if err := procutils.NewCommand("mkdir", "-p", s.Path).Run(); err != nil {
c <- err
return
}
}
if !fileutils2.IsDir(s.Path) {
c <- fmt.Errorf("path %s isn't directory", s.Path)
}
if !fileutils2.Writable(s.Path) {
c <- fmt.Errorf("dir %s not writable", s.Path)
}
c <- nil
}()
var err error
select {
case err = <-c:
break
case <-time.After(time.Second * 10):
err = ErrStorageTimeout
}
if fileutils2.IsDir(s.Path) && fileutils2.Writable(s.Path) {
return true
} else {
return false
}
return err
}
func (s *SLocalStorage) DeleteDiskfile(diskpath string) error {
+16 -5
View File
@@ -622,11 +622,22 @@ func (s *SRbdStorage) CreateDisk(diskId string) IDisk {
return disk
}
func (s *SRbdStorage) Accessible() bool {
_, err := s.withCluster(func(conn *rados.Conn) (interface{}, error) {
return conn.ListPools()
})
return err == nil
func (s *SRbdStorage) Accessible() error {
var c = make(chan error)
go func() {
_, err := s.withCluster(func(conn *rados.Conn) (interface{}, error) {
return conn.ListPools()
})
c <- err
}()
var err error
select {
case err = <-c:
break
case <-time.After(time.Second * 10):
err = ErrStorageTimeout
}
return err
}
func (s *SRbdStorage) SaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {