mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-03-24 10:45:06 +00:00
fix: show a warning when SQLite DB is stored on NFS/SMB/FUSE (#1381)
This commit is contained in:
committed by
GitHub
parent
95e9af4bbf
commit
2b5401dd2f
@@ -34,7 +34,8 @@ func NewDatabase() (db *gorm.DB, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run migrations
|
// Run migrations
|
||||||
if err := utils.MigrateDatabase(sqlDb); err != nil {
|
err = utils.MigrateDatabase(sqlDb)
|
||||||
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to run migrations: %w", err)
|
return nil, fmt.Errorf("failed to run migrations: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +43,10 @@ func NewDatabase() (db *gorm.DB, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ConnectDatabase() (db *gorm.DB, err error) {
|
func ConnectDatabase() (db *gorm.DB, err error) {
|
||||||
var dialector gorm.Dialector
|
var (
|
||||||
|
dialector gorm.Dialector
|
||||||
|
sqliteNetworkFilesystem bool
|
||||||
|
)
|
||||||
|
|
||||||
// Choose the correct database provider
|
// Choose the correct database provider
|
||||||
var onConnFn func(conn *sql.DB)
|
var onConnFn func(conn *sql.DB)
|
||||||
@@ -63,6 +67,14 @@ func ConnectDatabase() (db *gorm.DB, err error) {
|
|||||||
if err := ensureSqliteDatabaseDir(dbPath); err != nil {
|
if err := ensureSqliteDatabaseDir(dbPath); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqliteNetworkFilesystem, err = utils.IsNetworkedFileSystem(filepath.Dir(dbPath))
|
||||||
|
if err != nil {
|
||||||
|
// Log the error only
|
||||||
|
slog.Warn("Failed to detect filesystem type for the SQLite database directory", slog.String("path", filepath.Dir(dbPath)), slog.Any("error", err))
|
||||||
|
} else if sqliteNetworkFilesystem {
|
||||||
|
slog.Warn("⚠️⚠️⚠️ SQLite databases should not be stored on a networked file system like NFS, SMB, or FUSE, as there's a risk of crashes and even database corruption", slog.String("path", filepath.Dir(dbPath)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before we connect, also make sure that there's a temporary folder for SQLite to write its data
|
// Before we connect, also make sure that there's a temporary folder for SQLite to write its data
|
||||||
|
|||||||
35
backend/internal/utils/networked_filesystem_linux.go
Normal file
35
backend/internal/utils/networked_filesystem_linux.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Filesystem magic values from Linux's include/uapi/linux/magic.h, used by statfs(2).
|
||||||
|
const (
|
||||||
|
nfsSuperMagic = 0x6969
|
||||||
|
smbSuperMagic = 0x517b
|
||||||
|
cifsSuperMagic = 0xff534d42
|
||||||
|
fuseSuperMagic = 0x65735546
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsNetworkedFileSystem reports whether path is on a filesystem that is known to be unsafe for SQLite, specifically NFS, SMB/CIFS, or FUSE mounts.
|
||||||
|
func IsNetworkedFileSystem(path string) (bool, error) {
|
||||||
|
var statfs syscall.Statfs_t
|
||||||
|
err := syscall.Statfs(path, &statfs)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("error executing statfs syscall: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statfs_t.Type is arch-dependent (for example, int32 on some systems and int64 on others).
|
||||||
|
// Normalize through uint32 first so signed values still preserve the Linux bit pattern for magic numbers such as CIFS (0xff534d42), then compare in a wide unsigned form.
|
||||||
|
//nolint:gosec
|
||||||
|
switch uint64(uint32(statfs.Type)) {
|
||||||
|
case nfsSuperMagic, smbSuperMagic, cifsSuperMagic, fuseSuperMagic:
|
||||||
|
return true, nil
|
||||||
|
default:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
8
backend/internal/utils/networked_filesystem_nonlinux.go
Normal file
8
backend/internal/utils/networked_filesystem_nonlinux.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//go:build !linux
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
// IsNetworkedFileSystem returns false on non-Linux systems because this detection is only used for Linux-specific statfs(2) filesystem magic values.
|
||||||
|
func IsNetworkedFileSystem(string) (bool, error) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user