database.scm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2017, 2019 Caleb Ristvedt <caleb.ristvedt@cune.org>
  3. ;;; Copyright © 2018, 2020 Ludovic Courtès <ludo@gnu.org>
  4. ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  5. ;;;
  6. ;;; This file is part of GNU Guix.
  7. ;;;
  8. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  9. ;;; under the terms of the GNU General Public License as published by
  10. ;;; the Free Software Foundation; either version 3 of the License, or (at
  11. ;;; your option) any later version.
  12. ;;;
  13. ;;; GNU Guix is distributed in the hope that it will be useful, but
  14. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;;; GNU General Public License for more details.
  17. ;;;
  18. ;;; You should have received a copy of the GNU General Public License
  19. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  20. (define-module (guix store database)
  21. #:use-module (sqlite3)
  22. #:use-module (guix config)
  23. #:use-module (guix gexp)
  24. #:use-module (guix serialization)
  25. #:use-module (guix store deduplication)
  26. #:use-module (guix base16)
  27. #:use-module (guix progress)
  28. #:use-module (guix build syscalls)
  29. #:use-module ((guix build utils)
  30. #:select (mkdir-p executable-file?))
  31. #:use-module (guix utils)
  32. #:use-module (guix build store-copy)
  33. #:use-module (srfi srfi-1)
  34. #:use-module (srfi srfi-11)
  35. #:use-module (srfi srfi-19)
  36. #:use-module (srfi srfi-26)
  37. #:use-module (rnrs io ports)
  38. #:use-module (ice-9 match)
  39. #:use-module (system foreign)
  40. #:export (sql-schema
  41. %default-database-file
  42. store-database-file
  43. with-database
  44. path-id
  45. sqlite-register
  46. register-path
  47. register-items
  48. %epoch
  49. reset-timestamps))
  50. ;;; Code for working with the store database directly.
  51. (define sql-schema
  52. ;; Name of the file containing the SQL scheme or #f.
  53. (make-parameter #f))
  54. (define sqlite-exec
  55. ;; XXX: This is was missing from guile-sqlite3 until
  56. ;; <https://notabug.org/guile-sqlite3/guile-sqlite3/commit/b87302f9bcd18a286fed57b2ea521845eb1131d7>.
  57. (let ((exec (pointer->procedure
  58. int
  59. (dynamic-func "sqlite3_exec" (@@ (sqlite3) libsqlite3))
  60. '(* * * * *))))
  61. (lambda (db text)
  62. (let ((ret (exec ((@@ (sqlite3) db-pointer) db)
  63. (string->pointer text)
  64. %null-pointer %null-pointer %null-pointer)))
  65. (unless (zero? ret)
  66. ((@@ (sqlite3) sqlite-error) db "sqlite-exec" ret))))))
  67. (define* (store-database-directory #:key prefix state-directory)
  68. "Return the store database directory, taking PREFIX and STATE-DIRECTORY into
  69. account when provided."
  70. ;; Priority for options: first what is given, then environment variables,
  71. ;; then defaults. %state-directory, %store-directory, and
  72. ;; %store-database-directory already handle the "environment variables /
  73. ;; defaults" question, so we only need to choose between what is given and
  74. ;; those.
  75. (cond (state-directory
  76. (string-append state-directory "/db"))
  77. (prefix
  78. (string-append prefix %localstatedir "/guix/db"))
  79. (else
  80. %store-database-directory)))
  81. (define* (store-database-file #:key prefix state-directory)
  82. "Return the store database file name, taking PREFIX and STATE-DIRECTORY into
  83. account when provided."
  84. (string-append (store-database-directory #:prefix prefix
  85. #:state-directory state-directory)
  86. "/db.sqlite"))
  87. (define (initialize-database db)
  88. "Initializing DB, an empty database, by creating all the tables and indexes
  89. as specified by SQL-SCHEMA."
  90. (define schema
  91. (or (sql-schema)
  92. (search-path %load-path "guix/store/schema.sql")))
  93. (sqlite-exec db (call-with-input-file schema get-string-all)))
  94. (define* (call-with-database file proc #:key (wal-mode? #t))
  95. "Pass PROC a database record corresponding to FILE. If FILE doesn't exist,
  96. create it and initialize it as a new database. Unless WAL-MODE? is set to #f,
  97. set journal_mode=WAL."
  98. (let ((new? (and (not (file-exists? file))
  99. (begin
  100. (mkdir-p (dirname file))
  101. #t)))
  102. (db (sqlite-open file)))
  103. ;; Using WAL breaks for the Hurd <https://bugs.gnu.org/42151>.
  104. (when wal-mode?
  105. ;; Turn DB in "write-ahead log" mode, which should avoid SQLITE_LOCKED
  106. ;; errors when we have several readers: <https://www.sqlite.org/wal.html>.
  107. (sqlite-exec db "PRAGMA journal_mode=WAL;"))
  108. ;; Install a busy handler such that, when the database is locked, sqlite
  109. ;; retries until 30 seconds have passed, at which point it gives up and
  110. ;; throws SQLITE_BUSY.
  111. (sqlite-exec db "PRAGMA busy_timeout = 30000;")
  112. (dynamic-wind noop
  113. (lambda ()
  114. (when new?
  115. (initialize-database db))
  116. (proc db))
  117. (lambda ()
  118. (sqlite-close db)))))
  119. ;; XXX: missing in guile-sqlite3@0.1.0
  120. (define SQLITE_BUSY 5)
  121. (define (call-with-SQLITE_BUSY-retrying thunk)
  122. "Call THUNK, retrying as long as it exits abnormally due to SQLITE_BUSY
  123. errors."
  124. (catch 'sqlite-error
  125. thunk
  126. (lambda (key who code errmsg)
  127. (if (= code SQLITE_BUSY)
  128. (call-with-SQLITE_BUSY-retrying thunk)
  129. (throw key who code errmsg)))))
  130. (define* (call-with-transaction db proc #:key restartable?)
  131. "Start a transaction with DB and run PROC. If PROC exits abnormally, abort
  132. the transaction, otherwise commit the transaction after it finishes.
  133. RESTARTABLE? may be set to a non-#f value when it is safe to run PROC multiple
  134. times. This may reduce contention for the database somewhat."
  135. (define (exec sql)
  136. (with-statement db sql stmt
  137. (sqlite-fold cons '() stmt)))
  138. ;; We might use begin immediate here so that if we need to retry, we figure
  139. ;; that out immediately rather than because some SQLITE_BUSY exception gets
  140. ;; thrown partway through PROC - in which case the part already executed
  141. ;; (which may contain side-effects!) might have to be executed again for
  142. ;; every retry.
  143. (exec (if restartable? "begin;" "begin immediate;"))
  144. (catch #t
  145. (lambda ()
  146. (let-values ((result (proc)))
  147. (exec "commit;")
  148. (apply values result)))
  149. (lambda args
  150. ;; The roll back may or may not have occurred automatically when the
  151. ;; error was generated. If it has occurred, this does nothing but signal
  152. ;; an error. If it hasn't occurred, this needs to be done.
  153. (false-if-exception (exec "rollback;"))
  154. (apply throw args))))
  155. (define* (call-with-savepoint db proc
  156. #:optional (savepoint-name "SomeSavepoint"))
  157. "Call PROC after creating a savepoint named SAVEPOINT-NAME. If PROC exits
  158. abnormally, rollback to that savepoint. In all cases, remove the savepoint
  159. prior to returning."
  160. (define (exec sql)
  161. (with-statement db sql stmt
  162. (sqlite-fold cons '() stmt)))
  163. (dynamic-wind
  164. (lambda ()
  165. (exec (string-append "SAVEPOINT " savepoint-name ";")))
  166. (lambda ()
  167. (catch #t
  168. proc
  169. (lambda args
  170. (exec (string-append "ROLLBACK TO " savepoint-name ";"))
  171. (apply throw args))))
  172. (lambda ()
  173. (exec (string-append "RELEASE " savepoint-name ";")))))
  174. (define* (call-with-retrying-transaction db proc #:key restartable?)
  175. (call-with-SQLITE_BUSY-retrying
  176. (lambda ()
  177. (call-with-transaction db proc #:restartable? restartable?))))
  178. (define* (call-with-retrying-savepoint db proc
  179. #:optional (savepoint-name
  180. "SomeSavepoint"))
  181. (call-with-SQLITE_BUSY-retrying
  182. (lambda ()
  183. (call-with-savepoint db proc savepoint-name))))
  184. (define %default-database-file
  185. ;; Default location of the store database.
  186. (string-append %store-database-directory "/db.sqlite"))
  187. (define-syntax with-database
  188. (syntax-rules ()
  189. "Open DB from FILE and close it when the dynamic extent of EXP... is left.
  190. If FILE doesn't exist, create it and initialize it as a new database. Pass
  191. #:wal-mode? to call-with-database."
  192. ((_ file db #:wal-mode? wal-mode? exp ...)
  193. (call-with-database file (lambda (db) exp ...) #:wal-mode? wal-mode?))
  194. ((_ file db exp ...)
  195. (call-with-database file (lambda (db) exp ...)))))
  196. (define (sqlite-finalize stmt)
  197. ;; As of guile-sqlite3 0.1.0, cached statements aren't reset when
  198. ;; sqlite-finalize is invoked on them (see
  199. ;; https://notabug.org/guile-sqlite3/guile-sqlite3/issues/12). This can
  200. ;; cause problems with automatically-started transactions, so we work around
  201. ;; it by wrapping sqlite-finalize so that sqlite-reset is always called.
  202. ;; This always works, because resetting a statement twice has no adverse
  203. ;; effects. We can remove this once the fixed guile-sqlite3 is widespread.
  204. (sqlite-reset stmt)
  205. ((@ (sqlite3) sqlite-finalize) stmt))
  206. (define (call-with-statement db sql proc)
  207. (let ((stmt (sqlite-prepare db sql #:cache? #t)))
  208. (dynamic-wind
  209. (const #t)
  210. (lambda ()
  211. (proc stmt))
  212. (lambda ()
  213. (sqlite-finalize stmt)))))
  214. (define-syntax-rule (with-statement db sql stmt exp ...)
  215. "Run EXP... with STMT bound to a prepared statement corresponding to the sql
  216. string SQL for DB."
  217. (call-with-statement db sql
  218. (lambda (stmt) exp ...)))
  219. (define (last-insert-row-id db)
  220. ;; XXX: (sqlite3) currently lacks bindings for 'sqlite3_last_insert_rowid'.
  221. ;; Work around that.
  222. (with-statement db "SELECT last_insert_rowid();" stmt
  223. (match (sqlite-fold cons '() stmt)
  224. ((#(id)) id)
  225. (_ #f))))
  226. (define path-id-sql
  227. "SELECT id FROM ValidPaths WHERE path = :path")
  228. (define* (path-id db path)
  229. "If PATH exists in the 'ValidPaths' table, return its numerical
  230. identifier. Otherwise, return #f."
  231. (with-statement db path-id-sql stmt
  232. (sqlite-bind-arguments stmt #:path path)
  233. (match (sqlite-fold cons '() stmt)
  234. ((#(id) . _) id)
  235. (_ #f))))
  236. (define update-sql
  237. "UPDATE ValidPaths SET hash = :hash, registrationTime = :time, deriver =
  238. :deriver, narSize = :size WHERE id = :id")
  239. (define insert-sql
  240. "INSERT INTO ValidPaths (path, hash, registrationTime, deriver, narSize)
  241. VALUES (:path, :hash, :time, :deriver, :size)")
  242. (define* (update-or-insert db #:key path deriver hash nar-size time)
  243. "The classic update-if-exists and insert-if-doesn't feature that sqlite
  244. doesn't exactly have... they've got something close, but it involves deleting
  245. and re-inserting instead of updating, which causes problems with foreign keys,
  246. of course. Returns the row id of the row that was modified or inserted."
  247. ;; It's important that querying the path-id and the insert/update operation
  248. ;; take place in the same transaction, as otherwise some other
  249. ;; process/thread/fiber could register the same path between when we check
  250. ;; whether it's already registered and when we register it, resulting in
  251. ;; duplicate paths (which, due to a 'unique' constraint, would cause an
  252. ;; exception to be thrown). With the default journaling mode this will
  253. ;; prevent writes from occurring during that sensitive time, but with WAL
  254. ;; mode it will instead arrange to return SQLITE_BUSY when a write occurs
  255. ;; between the start of a read transaction and its upgrading to a write
  256. ;; transaction (see https://sqlite.org/rescode.html#busy_snapshot).
  257. ;; Experimentally, it seems this SQLITE_BUSY will ignore a busy_timeout and
  258. ;; immediately return (makes sense, since waiting won't change anything).
  259. ;; Note that when that kind of SQLITE_BUSY error is returned, it will keep
  260. ;; being returned every time we try to upgrade the same outermost
  261. ;; transaction to a write transaction. So when retrying, we have to restart
  262. ;; the *outermost* write transaction. We can't inherently tell whether
  263. ;; we're the outermost write transaction, so we leave the retry-handling to
  264. ;; the caller.
  265. (call-with-savepoint db
  266. (lambda ()
  267. (let ((id (path-id db path)))
  268. (if id
  269. (with-statement db update-sql stmt
  270. (sqlite-bind-arguments stmt #:id id
  271. #:deriver deriver
  272. #:hash hash #:size nar-size #:time time)
  273. (sqlite-fold cons '() stmt))
  274. (with-statement db insert-sql stmt
  275. (sqlite-bind-arguments stmt
  276. #:path path #:deriver deriver
  277. #:hash hash #:size nar-size #:time time)
  278. (sqlite-fold cons '() stmt)))
  279. (last-insert-row-id db)))))
  280. (define add-reference-sql
  281. "INSERT OR REPLACE INTO Refs (referrer, reference) VALUES (:referrer, :reference);")
  282. (define (add-references db referrer references)
  283. "REFERRER is the id of the referring store item, REFERENCES is a list
  284. ids of items referred to."
  285. (with-statement db add-reference-sql stmt
  286. (for-each (lambda (reference)
  287. (sqlite-reset stmt)
  288. (sqlite-bind-arguments stmt #:referrer referrer
  289. #:reference reference)
  290. (sqlite-fold cons '() stmt))
  291. references)))
  292. (define* (sqlite-register db #:key path (references '())
  293. deriver hash nar-size time)
  294. "Registers this stuff in DB. PATH is the store item to register and
  295. REFERENCES is the list of store items PATH refers to; DERIVER is the '.drv'
  296. that produced PATH, HASH is the base16-encoded Nix sha256 hash of
  297. PATH (prefixed with \"sha256:\"), and NAR-SIZE is the size in bytes PATH after
  298. being converted to nar form. TIME is the registration time to be recorded in
  299. the database or #f, meaning \"right now\".
  300. Every store item in REFERENCES must already be registered."
  301. (let ((id (update-or-insert db #:path path
  302. #:deriver deriver
  303. #:hash hash
  304. #:nar-size nar-size
  305. #:time (time-second
  306. (or time
  307. (current-time time-utc))))))
  308. ;; Call 'path-id' on each of REFERENCES. This ensures we get a
  309. ;; "non-NULL constraint" failure if one of REFERENCES is unregistered.
  310. (add-references db id
  311. (map (cut path-id db <>) references))))
  312. ;;;
  313. ;;; High-level interface.
  314. ;;;
  315. (define* (reset-timestamps file #:key preserve-permissions?)
  316. "Reset the modification time on FILE and on all the files it contains, if
  317. it's a directory. Canonicalize file permissions unless PRESERVE-PERMISSIONS?
  318. is true."
  319. ;; Note: We're resetting to one second after the Epoch like 'guix-daemon'
  320. ;; has always done.
  321. (let loop ((file file)
  322. (type (stat:type (lstat file))))
  323. (case type
  324. ((directory)
  325. (unless preserve-permissions?
  326. (chmod file #o555))
  327. (utime file 1 1 0 0)
  328. (let ((parent file))
  329. (for-each (match-lambda
  330. (("." . _) #f)
  331. ((".." . _) #f)
  332. ((file . properties)
  333. (let ((file (string-append parent "/" file)))
  334. (loop file
  335. (match (assoc-ref properties 'type)
  336. ((or 'unknown #f)
  337. (stat:type (lstat file)))
  338. (type type))))))
  339. (scandir* parent))))
  340. ((symlink)
  341. (utime file 1 1 0 0 AT_SYMLINK_NOFOLLOW))
  342. (else
  343. (unless preserve-permissions?
  344. (chmod file (if (executable-file? file) #o555 #o444)))
  345. (utime file 1 1 0 0)))))
  346. (define* (register-path path
  347. #:key (references '()) deriver prefix
  348. state-directory (deduplicate? #t)
  349. (reset-timestamps? #t)
  350. (schema (sql-schema)))
  351. "Register PATH as a valid store file, with REFERENCES as its list of
  352. references, and DERIVER as its deriver (.drv that led to it.) If PREFIX is
  353. given, it must be the name of the directory containing the new store to
  354. initialize; if STATE-DIRECTORY is given, it must be a string containing the
  355. absolute file name to the state directory of the store being initialized.
  356. Return #t on success.
  357. Use with care as it directly modifies the store! This is primarily meant to
  358. be used internally by the daemon's build hook.
  359. PATH must be protected from GC and locked during execution of this, typically
  360. by adding it as a temp-root."
  361. (define db-file
  362. (store-database-file #:prefix prefix
  363. #:state-directory state-directory))
  364. (parameterize ((sql-schema schema))
  365. (with-database db-file db
  366. (register-items db (list (store-info path deriver references))
  367. #:prefix prefix
  368. #:deduplicate? deduplicate?
  369. #:reset-timestamps? reset-timestamps?
  370. #:log-port (%make-void-port "w")))))
  371. (define %epoch
  372. ;; When it all began.
  373. (make-time time-utc 0 1))
  374. (define* (register-items db items
  375. #:key prefix
  376. (deduplicate? #t)
  377. (reset-timestamps? #t)
  378. registration-time
  379. (log-port (current-error-port)))
  380. "Register all of ITEMS, a list of <store-info> records as returned by
  381. 'read-reference-graph', in DB. ITEMS must be in topological order (with
  382. leaves first.) REGISTRATION-TIME must be the registration time to be recorded
  383. in the database; #f means \"now\". Write a progress report to LOG-PORT. All
  384. of ITEMS must be protected from GC and locked during execution of this,
  385. typically by adding them as temp-roots."
  386. (define store-dir
  387. (if prefix
  388. (string-append prefix %storedir)
  389. %store-directory))
  390. (define (register db item)
  391. (define to-register
  392. (if prefix
  393. (string-append %storedir "/" (basename (store-info-item item)))
  394. ;; note: we assume here that if path is, for example,
  395. ;; /foo/bar/gnu/store/thing.txt and prefix isn't given, then an
  396. ;; environment variable has been used to change the store directory
  397. ;; to /foo/bar/gnu/store, since otherwise real-path would end up
  398. ;; being /gnu/store/thing.txt, which is probably not the right file
  399. ;; in this case.
  400. (store-info-item item)))
  401. (define real-file-name
  402. (string-append store-dir "/" (basename (store-info-item item))))
  403. ;; When TO-REGISTER is already registered, skip it. This makes a
  404. ;; significant differences when 'register-closures' is called
  405. ;; consecutively for overlapping closures such as 'system' and 'bootcfg'.
  406. (unless (path-id db to-register)
  407. (when reset-timestamps?
  408. (reset-timestamps real-file-name))
  409. (let-values (((hash nar-size) (nar-sha256 real-file-name)))
  410. (call-with-retrying-transaction db
  411. (lambda ()
  412. (sqlite-register db #:path to-register
  413. #:references (store-info-references item)
  414. #:deriver (store-info-deriver item)
  415. #:hash (string-append
  416. "sha256:"
  417. (bytevector->base16-string hash))
  418. #:nar-size nar-size
  419. #:time registration-time)))
  420. (when deduplicate?
  421. (deduplicate real-file-name hash #:store store-dir)))))
  422. (let* ((prefix (format #f "registering ~a items" (length items)))
  423. (progress (progress-reporter/bar (length items)
  424. prefix log-port)))
  425. (call-with-progress-reporter progress
  426. (lambda (report)
  427. (for-each (lambda (item)
  428. (register db item)
  429. (report))
  430. items)))))