aboutsummaryrefslogtreecommitdiff
path: root/Database
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2017-02-13 17:30:28 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2017-02-13 17:39:16 -0400
commitab15aba7e4eb7fcc6d1e1423622a0e1bc04c567e (patch)
tree859c5098a50217580cb803dd99e166ad76b9e814 /Database
parent6e5180c8d52cabffff00fda0682b6cb280e95b36 (diff)
Work around sqlite's incorrect handling of umask when creating databases.
Refactored some common code into initDb. This only deals with the problem when creating new databases. If a repo got bad permissions into it, it's up to the user to deal with it. This commit was sponsored by Ole-Morten Duesund on Patreon.
Diffstat (limited to 'Database')
-rw-r--r--Database/Fsck.hs16
-rw-r--r--Database/Handle.hs21
-rw-r--r--Database/Init.hs55
-rw-r--r--Database/Keys.hs8
-rw-r--r--Database/Queue.hs1
5 files changed, 60 insertions, 41 deletions
diff --git a/Database/Fsck.hs b/Database/Fsck.hs
index 702b52925..9affeac85 100644
--- a/Database/Fsck.hs
+++ b/Database/Fsck.hs
@@ -22,11 +22,10 @@ module Database.Fsck (
import Database.Types
import qualified Database.Queue as H
+import Database.Init
import Annex.Locations
-import Utility.PosixFiles
import Utility.Exception
import Annex.Common
-import Annex.Perms
import Annex.LockFile
import Database.Persist.TH
@@ -61,17 +60,8 @@ openDb u = do
dbdir <- fromRepo (gitAnnexFsckDbDir u)
let db = dbdir </> "db"
unlessM (liftIO $ doesFileExist db) $ do
- let tmpdbdir = dbdir ++ ".tmp"
- let tmpdb = tmpdbdir </> "db"
- liftIO $ do
- createDirectoryIfMissing True tmpdbdir
- H.initDb tmpdb $ void $
- runMigrationSilent migrateFsck
- setAnnexDirPerm tmpdbdir
- setAnnexFilePerm tmpdb
- liftIO $ do
- void $ tryIO $ removeDirectoryRecursive dbdir
- rename tmpdbdir dbdir
+ initDb db $ void $
+ runMigrationSilent migrateFsck
lockFileCached =<< fromRepo (gitAnnexFsckDbLock u)
h <- liftIO $ H.openDbQueue db "fscked"
return $ FsckHandle h u
diff --git a/Database/Handle.hs b/Database/Handle.hs
index d84ce5b62..7827be749 100644
--- a/Database/Handle.hs
+++ b/Database/Handle.hs
@@ -9,7 +9,6 @@
module Database.Handle (
DbHandle,
- initDb,
openDb,
TableName,
queryDb,
@@ -38,26 +37,6 @@ import System.IO
- the database. It has a MVar which Jobs are submitted to. -}
data DbHandle = DbHandle (Async ()) (MVar Job)
-{- Ensures that the database is initialized. Pass the migration action for
- - the database.
- -
- - The database is initialized using WAL mode, to prevent readers
- - from blocking writers, and prevent a writer from blocking readers.
- -}
-initDb :: FilePath -> SqlPersistM () -> IO ()
-initDb f migration = do
- let db = T.pack f
- enableWAL db
- runSqlite db migration
-
-enableWAL :: T.Text -> IO ()
-enableWAL db = do
- conn <- Sqlite.open db
- stmt <- Sqlite.prepare conn (T.pack "PRAGMA journal_mode=WAL;")
- void $ Sqlite.step stmt
- void $ Sqlite.finalize stmt
- Sqlite.close conn
-
{- Name of a table that should exist once the database is initialized. -}
type TableName = String
diff --git a/Database/Init.hs b/Database/Init.hs
new file mode 100644
index 000000000..d7a7f6842
--- /dev/null
+++ b/Database/Init.hs
@@ -0,0 +1,55 @@
+{- Persistent sqlite database initialization
+ -
+ - Copyright 2015-2017 Joey Hess <id@joeyh.name>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Database.Init where
+
+import Annex.Common
+import Annex.Perms
+import Utility.FileMode
+
+import Database.Persist.Sqlite
+import qualified Database.Sqlite as Sqlite
+import Control.Monad.IO.Class (liftIO)
+import qualified Data.Text as T
+
+{- Ensures that the database is freshly initialized. Deletes any
+ - existing database. Pass the migration action for the database.
+ -
+ - The database is initialized using WAL mode, to prevent readers
+ - from blocking writers, and prevent a writer from blocking readers.
+ -
+ - The permissions of the database are set based on the
+ - core.sharedRepository setting. Setting these permissions on the main db
+ - file causes Sqlite to always use the same permissions for additional
+ - files it writes later on
+ -}
+initDb :: FilePath -> SqlPersistM () -> Annex ()
+initDb db migration = do
+ let dbdir = takeDirectory db
+ let tmpdbdir = dbdir ++ ".tmp"
+ let tmpdb = tmpdbdir </> "db"
+ liftIO $ do
+ createDirectoryIfMissing True tmpdbdir
+ let tdb = T.pack tmpdb
+ enableWAL tdb
+ runSqlite tdb migration
+ setAnnexDirPerm tmpdbdir
+ -- Work around sqlite bug that prevents it from honoring
+ -- less restrictive umasks.
+ liftIO $ setFileMode tmpdb =<< defaultFileMode
+ setAnnexFilePerm tmpdb
+ liftIO $ do
+ void $ tryIO $ removeDirectoryRecursive dbdir
+ rename tmpdbdir dbdir
+
+enableWAL :: T.Text -> IO ()
+enableWAL db = do
+ conn <- Sqlite.open db
+ stmt <- Sqlite.prepare conn (T.pack "PRAGMA journal_mode=WAL;")
+ void $ Sqlite.step stmt
+ void $ Sqlite.finalize stmt
+ Sqlite.close conn
diff --git a/Database/Keys.hs b/Database/Keys.hs
index 0f2f34930..b9440ac1a 100644
--- a/Database/Keys.hs
+++ b/Database/Keys.hs
@@ -25,11 +25,11 @@ import qualified Database.Keys.SQL as SQL
import Database.Types
import Database.Keys.Handle
import qualified Database.Queue as H
+import Database.Init
import Annex.Locations
import Annex.Common hiding (delete)
import Annex.Version (versionUsesKeysDatabase)
import qualified Annex
-import Annex.Perms
import Annex.LockFile
import Utility.InodeCache
import Annex.InodeSentinal
@@ -120,11 +120,7 @@ openDb createdb _ = catchPermissionDenied permerr $ withExclusiveLock gitAnnexKe
case (dbexists, createdb) of
(True, _) -> open db
(False, True) -> do
- liftIO $ do
- createDirectoryIfMissing True dbdir
- H.initDb db SQL.createTables
- setAnnexDirPerm dbdir
- setAnnexFilePerm db
+ initDb db SQL.createTables
open db
(False, False) -> return DbUnavailable
where
diff --git a/Database/Queue.hs b/Database/Queue.hs
index c4186b8c8..143871079 100644
--- a/Database/Queue.hs
+++ b/Database/Queue.hs
@@ -9,7 +9,6 @@
module Database.Queue (
DbQueue,
- initDb,
openDbQueue,
queryDbQueue,
closeDbQueue,