10
10
#include " nar-info-disk-cache.hh"
11
11
#include " nar-accessor.hh"
12
12
#include " json.hh"
13
+ #include " thread-pool.hh"
13
14
14
15
#include < chrono>
15
-
16
16
#include < future>
17
+ #include < regex>
18
+
19
+ #include < nlohmann/json.hpp>
17
20
18
21
namespace nix {
19
22
@@ -139,6 +142,11 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
139
142
140
143
auto accessor_ = std::dynamic_pointer_cast<RemoteFSAccessor>(accessor);
141
144
145
+ auto narAccessor = makeNarAccessor (nar);
146
+
147
+ if (accessor_)
148
+ accessor_->addToCache (info.path , *nar, narAccessor);
149
+
142
150
/* Optionally write a JSON file containing a listing of the
143
151
contents of the NAR. */
144
152
if (writeNARListing) {
@@ -148,11 +156,6 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
148
156
JSONObject jsonRoot (jsonOut);
149
157
jsonRoot.attr (" version" , 1 );
150
158
151
- auto narAccessor = makeNarAccessor (nar);
152
-
153
- if (accessor_)
154
- accessor_->addToCache (info.path , *nar, narAccessor);
155
-
156
159
{
157
160
auto res = jsonRoot.placeholder (" root" );
158
161
listNar (res, narAccessor, " " , true );
@@ -162,11 +165,6 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
162
165
upsertFile (storePathToHash (info.path ) + " .ls" , jsonOut.str (), " application/json" );
163
166
}
164
167
165
- else {
166
- if (accessor_)
167
- accessor_->addToCache (info.path , *nar, makeNarAccessor (nar));
168
- }
169
-
170
168
/* Compress the NAR. */
171
169
narInfo->compression = compression;
172
170
auto now1 = std::chrono::steady_clock::now ();
@@ -181,12 +179,70 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
181
179
% ((1.0 - (double ) narCompressed->size () / nar->size ()) * 100.0 )
182
180
% duration);
183
181
184
- /* Atomically write the NAR file. */
185
182
narInfo->url = " nar/" + narInfo->fileHash .to_string (Base32, false ) + " .nar"
186
183
+ (compression == " xz" ? " .xz" :
187
184
compression == " bzip2" ? " .bz2" :
188
185
compression == " br" ? " .br" :
189
186
" " );
187
+
188
+ /* Optionally maintain an index of DWARF debug info files
189
+ consisting of JSON files named 'debuginfo/<build-id>' that
190
+ specify the NAR file and member containing the debug info. */
191
+ if (writeDebugInfo) {
192
+
193
+ std::string buildIdDir = " /lib/debug/.build-id" ;
194
+
195
+ if (narAccessor->stat (buildIdDir).type == FSAccessor::tDirectory) {
196
+
197
+ ThreadPool threadPool (25 );
198
+
199
+ auto doFile = [&](std::string member, std::string key, std::string target) {
200
+ checkInterrupt ();
201
+
202
+ nlohmann::json json;
203
+ json[" archive" ] = target;
204
+ json[" member" ] = member;
205
+
206
+ // FIXME: or should we overwrite? The previous link may point
207
+ // to a GC'ed file, so overwriting might be useful...
208
+ if (fileExists (key)) return ;
209
+
210
+ printMsg (lvlTalkative, " creating debuginfo link from '%s' to '%s'" , key, target);
211
+
212
+ upsertFile (key, json.dump (), " application/json" );
213
+ };
214
+
215
+ std::regex regex1 (" ^[0-9a-f]{2}$" );
216
+ std::regex regex2 (" ^[0-9a-f]{38}\\ .debug$" );
217
+
218
+ for (auto & s1 : narAccessor->readDirectory (buildIdDir)) {
219
+ auto dir = buildIdDir + " /" + s1;
220
+
221
+ if (narAccessor->stat (dir).type != FSAccessor::tDirectory
222
+ || !std::regex_match (s1, regex1))
223
+ continue ;
224
+
225
+ for (auto & s2 : narAccessor->readDirectory (dir)) {
226
+ auto debugPath = dir + " /" + s2;
227
+
228
+ if (narAccessor->stat (debugPath).type != FSAccessor::tRegular
229
+ || !std::regex_match (s2, regex2))
230
+ continue ;
231
+
232
+ auto buildId = s1 + s2;
233
+
234
+ std::string key = " debuginfo/" + buildId;
235
+ std::string target = " ../" + narInfo->url ;
236
+
237
+ threadPool.enqueue (std::bind (doFile, std::string (debugPath, 1 ), key, target));
238
+ }
239
+ }
240
+
241
+ threadPool.process ();
242
+ }
243
+ }
244
+
245
+ /* Atomically write the NAR file. */
190
246
if (repair || !fileExists (narInfo->url )) {
191
247
stats.narWrite ++;
192
248
upsertFile (narInfo->url , *narCompressed, " application/x-nix-nar" );
0 commit comments