Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/portupgrade
Path: blob/master/lib/pkgtools/pkgdbtools.rb
102 views
1
# vim: set sts=2 sw=2 ts=8 et:
2
#
3
# Copyright (c) 2001-2004 Akinori MUSHA <[email protected]>
4
# Copyright (c) 2006-2008 Sergey Matveychuk <[email protected]>
5
# Copyright (c) 2009-2012 Stanislav Sedov <[email protected]>
6
#
7
# All rights reserved.
8
#
9
# Redistribution and use in source and binary forms, with or without
10
# modification, are permitted provided that the following conditions
11
# are met:
12
# 1. Redistributions of source code must retain the above copyright
13
# notice, this list of conditions and the following disclaimer.
14
# 2. Redistributions in binary form must reproduce the above copyright
15
# notice, this list of conditions and the following disclaimer in the
16
# documentation and/or other materials provided with the distribution.
17
#
18
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
# SUCH DAMAGE.
29
#
30
31
module PkgDBTools
32
def PkgDBTools.remove_lock(file_name, force = false)
33
return if file_name.nil?
34
35
if !file_name.nil? && File.exist?(file_name) && !File.zero?(file_name) &&
36
file = File.open(file_name)
37
38
pid, mode = file.gets.split(' ')
39
file.close
40
41
# Remove only our lock file unless force
42
File.unlink(file_name) if pid.to_i == $$ || force
43
end
44
end
45
46
def db_dir()
47
unless @db_dir
48
set_db_dir(nil) # initialize with the default value
49
end
50
51
@db_dir
52
end
53
54
def db_driver()
55
unless @db_driver
56
set_db_driver(nil) # initialize with the default value
57
end
58
59
@db_driver
60
end
61
62
def db_driver=(new_db_driver)
63
begin
64
case new_db_driver || ENV['PKG_DBDRIVER'] || 'bdb_btree'
65
when 'pkg'
66
@db_driver = :pkg
67
when 'bdb_btree'
68
@db_driver = :bdb_btree
69
when 'bdb_hash', 'bdb'
70
@db_driver = :bdb_hash
71
when 'bdb1_btree', 'btree'
72
@db_driver = :bdb1_btree
73
when 'bdb1_hash', 'hash', 'bdb1'
74
@db_driver = :bdb1_hash
75
else
76
@db_driver = :dbm_hash
77
end
78
79
case @db_driver
80
when :pkg
81
next_driver = nil
82
when :bdb_btree
83
next_driver = 'bdb1_btree'
84
require 'bdb'
85
@db_params = ["set_pagesize" => 1024, "set_cachesize" => [0, 32 * 1024, 0]]
86
when :bdb_hash
87
next_driver = 'bdb1_hash'
88
require 'bdb'
89
@db_params = ["set_pagesize" => 1024, "set_cachesize" => [0, 32 * 1024, 0]]
90
when :bdb1_btree
91
next_driver = 'dbm'
92
require 'bdb1'
93
@db_params = ["set_pagesize" => 1024, "set_cachesize" => 32 * 1024]
94
when :bdb1_hash
95
next_driver = 'dbm'
96
require 'bdb1'
97
@db_params = ["set_pagesize" => 1024, "set_cachesize" => 32 * 1024]
98
else
99
next_driver = nil
100
require 'dbm'
101
end
102
rescue LoadError
103
if next_driver.nil?
104
raise DBError, "No driver is available!"
105
end
106
107
new_db_driver = next_driver
108
retry
109
end
110
111
@db_driver
112
end
113
alias set_db_driver db_driver=
114
115
def date_db_file
116
return Time.at(0) if $pkgdb.with_pkgng?
117
File.mtime(@db_file) rescue Time.at(0)
118
end
119
120
def check_db_version
121
file_db_version = Marshal.load(@db[':db_version'])
122
123
file_db_version[0] == @db_version[0] && file_db_version[1] >= @db_version[1]
124
rescue => e
125
return false
126
end
127
128
def lock_db_on_read
129
return if @lock_file.nil?
130
count = 0
131
while FileTest.exist?(@lock_file)
132
if Time::now() - File.stat(@lock_file).mtime > 120
133
puts "** Stale lock file was found. Removed."
134
PkgDBTools.remove_lock(@lock_file, true)
135
break
136
end
137
sleep 1 if File.zero?(@lock_file)
138
file = File.open(@lock_file)
139
pid, mode = file.gets.chomp.split(' ')
140
file.close
141
if mode == 'w'
142
if count == 0
143
puts "** Database file locked for writing. Waiting."
144
end
145
sleep 1
146
count += 1
147
if count > 120
148
puts "** Timeout. The lock looks dead. Remove it."
149
PkgDBTools.remove_lock(@lock_file, true)
150
end
151
else
152
# ignore read lock
153
break
154
end
155
end
156
157
file = File.open(@lock_file, "w")
158
file.puts "#$$ r"
159
file.close
160
end
161
162
def lock_db_on_write
163
return if @lock_file.nil?
164
count = 0
165
while FileTest.exist?(@lock_file)
166
if Time::now() - File.stat(@lock_file).mtime > 120
167
STDERR.puts "** Stale lock file was found. Removed."
168
PkgDBTools.remove_lock(@lock_file, true)
169
break
170
end
171
if count == 0
172
STDERR.puts "** Database file locked. Waiting."
173
end
174
sleep 1
175
count += 1
176
if count > 120
177
STDERR.puts "** Timeout. The lock looks dead. Remove it."
178
PkgDBTools.remove_lock(@lock_file, true)
179
end
180
end
181
182
file = File.open(@lock_file, "w")
183
file.puts "#$$ w"
184
file.close
185
end
186
187
def unlock_db
188
PkgDBTools.remove_lock(@lock_file)
189
end
190
191
def get_db(mode, perm)
192
case db_driver
193
when :pkg
194
db = {}
195
when :bdb_btree
196
db = BDB::Btree.open @db_file, nil, mode, perm, *@db_params
197
when :bdb_hash
198
db = BDB::Hash.open @db_file, nil, mode, perm, *@db_params
199
when :bdb1_btree
200
db = BDB1::Btree.open @db_file, mode, perm, *@db_params
201
when :bdb1_hash
202
db = BDB1::Hash.open @db_file, mode, perm, *@db_params
203
else
204
if mode == 'w+'
205
File.unlink(@db_file) if File.exist?(@db_file)
206
end
207
db = DBM.open(@db_filebase)
208
end
209
db
210
end
211
212
def open_db_for_read!
213
close_db
214
215
lock_db_on_read
216
@db = get_db('r', 0)
217
end
218
219
def open_db_for_update!
220
close_db
221
222
lock_db_on_write
223
@db = get_db('r+', 0664)
224
end
225
226
def open_db_for_rebuild!
227
close_db
228
229
lock_db_on_write
230
@db = get_db('w+', 0664)
231
end
232
233
def close_db
234
unlock_db
235
if @db and @db_driver != :pkg
236
@db.close
237
@db = nil
238
end
239
end
240
241
module_function :db_dir, :db_driver, :set_db_driver,
242
:check_db_version, :open_db_for_read!, :open_db_for_update!,
243
:open_db_for_rebuild!, :close_db
244
public :db_dir, :close_db
245
end
246
247
248