mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-03-24 06:05:08 +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
|
||||
if err := utils.MigrateDatabase(sqlDb); err != nil {
|
||||
err = utils.MigrateDatabase(sqlDb)
|
||||
if err != nil {
|
||||
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) {
|
||||
var dialector gorm.Dialector
|
||||
var (
|
||||
dialector gorm.Dialector
|
||||
sqliteNetworkFilesystem bool
|
||||
)
|
||||
|
||||
// Choose the correct database provider
|
||||
var onConnFn func(conn *sql.DB)
|
||||
@@ -63,6 +67,14 @@ func ConnectDatabase() (db *gorm.DB, err error) {
|
||||
if err := ensureSqliteDatabaseDir(dbPath); err != nil {
|
||||
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
|
||||
|
||||
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