fix(import): prevent sqlite disk I/O error by validating temp DB then swapping
Some checks failed
Release 3X-UI / build (386) (push) Has been cancelled
Release 3X-UI / build (amd64) (push) Has been cancelled
Release 3X-UI / build (arm64) (push) Has been cancelled
Release 3X-UI / build (armv5) (push) Has been cancelled
Release 3X-UI / build (armv6) (push) Has been cancelled
Release 3X-UI / build (armv7) (push) Has been cancelled
Release 3X-UI / build (s390x) (push) Has been cancelled
Release 3X-UI / Build for Windows (amd64) (push) Has been cancelled

This commit is contained in:
mhsanaei
2025-10-14 22:03:17 +02:00
parent 8afa39144e
commit d8523bbdac
2 changed files with 46 additions and 6 deletions

View File

@@ -942,13 +942,26 @@ func (s *ServerService) ImportDB(file multipart.File) error {
return common.NewErrorf("Error saving db: %v", err)
}
// Check if we can init the db or not
if err = database.InitDB(tempPath); err != nil {
return common.NewErrorf("Error checking db: %v", err)
// Close temp file before opening via sqlite
if err = tempFile.Close(); err != nil {
return common.NewErrorf("Error closing temporary db file: %v", err)
}
tempFile = nil
// Validate integrity (no migrations / side effects)
if err = database.ValidateSQLiteDB(tempPath); err != nil {
return common.NewErrorf("Invalid or corrupt db file: %v", err)
}
// Stop Xray
s.StopXrayService()
// Stop Xray (ignore error but log)
if errStop := s.StopXrayService(); errStop != nil {
logger.Warningf("Failed to stop Xray before DB import: %v", errStop)
}
// Close existing DB to release file locks (especially on Windows)
if errClose := database.CloseDB(); errClose != nil {
logger.Warningf("Failed to close existing DB before replacement: %v", errClose)
}
// Backup the current database for fallback
fallbackPath := fmt.Sprintf("%s.backup", config.GetDBPath())
@@ -983,7 +996,7 @@ func (s *ServerService) ImportDB(file multipart.File) error {
return common.NewErrorf("Error moving db file: %v", err)
}
// Migrate DB
// Open & migrate new DB
if err = database.InitDB(config.GetDBPath()); err != nil {
if errRename := os.Rename(fallbackPath, config.GetDBPath()); errRename != nil {
return common.NewErrorf("Error migrating db and restoring fallback: %v", errRename)