• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paticcaa / pain / 18547817035

16 Oct 2025 01:53AM UTC coverage: 55.128% (-0.06%) from 55.184%
18547817035

Pull #15

github

web-flow
Merge 1928fd14d into fdb473e85
Pull Request #15: spdk 去除-lmana, 去除无用链接选项

1660 of 4120 branches covered (40.29%)

Branch coverage included in aggregate %.

1936 of 2403 relevant lines covered (80.57%)

498.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.15
/src/deva/deva.cc
1
#include "deva/deva.h"
2
#include <pain/base/plog.h>
3
#include <pain/base/uuid.h>
4
#include "common/object_id_util.h"
5
#include "common/txn_manager.h"
6
#include "deva/macro.h"
7

8
#define DEVA_METHOD(name)                                                                                              \
9
    Status Deva::name([[maybe_unused]] int32_t version,                                                                \
10
                      [[maybe_unused]] const pain::proto::deva::store::name##Request* request,                         \
11
                      [[maybe_unused]] pain::proto::deva::store::name##Response* response,                             \
12
                      [[maybe_unused]] int64_t index)
13

14
namespace pain::deva {
15

16
Status Deva::create(const std::string& path, const ObjectId& id, FileType type) {
76✔
17
    SPAN(span);
380!
18
    PLOG_DEBUG(("desc", "create")("path", path)("id", id.str())("type", type));
76✔
19
    // get parent
20
    std::filesystem::path file_path(path);
76!
21
    auto dir = file_path.parent_path();
76!
22
    auto filename = file_path.filename();
76!
23
    auto file_type = FileType::kFile;
76✔
24
    ObjectId parent_dir_uuid;
76✔
25
    auto status = _namespace.lookup(dir.c_str(), &parent_dir_uuid, &file_type);
76!
26
    if (!status.ok()) {
76!
27
        return status;
×
28
    }
29

30
    if (file_type != FileType::kDirectory) {
76!
31
        return Status(EINVAL, fmt::format("{} is not a directory", dir.c_str()));
×
32
    }
33

34
    status = _namespace.create(parent_dir_uuid, filename, type, id);
76!
35
    if (!status.ok()) {
76!
36
        return status;
×
37
    }
38

39
    return Status::OK();
76✔
40
}
228✔
41

42
DEVA_METHOD(CreateFile) {
37✔
43
    SPAN(span);
185!
44
    PLOG_DEBUG(("desc", "create_file")("version", version)("index", index)("request", request->DebugString()));
37✔
45
    auto& path = request->path();
37!
46
    auto& file_id = request->file_id();
37!
47
    ObjectId file_uuid = common::from_proto(file_id);
37!
48
    auto status = create(path, file_uuid, FileType::kFile);
37!
49
    if (!status.ok()) {
37!
50
        return status;
×
51
    }
52
    auto file_info = response->mutable_file_info();
37!
53
    common::to_proto(file_uuid, file_info->mutable_file_id());
37!
54
    file_info->set_type(pain::proto::FileType::FILE_TYPE_FILE);
37!
55
    file_info->set_size(0);
37!
56
    file_info->set_atime(request->atime());
37!
57
    file_info->set_mtime(request->mtime());
37!
58
    file_info->set_ctime(request->ctime());
37!
59
    file_info->set_mode(request->mode());
37!
60
    file_info->set_uid(request->uid());
37!
61
    file_info->set_gid(request->gid());
37!
62
    status = update_file_info(file_uuid, *file_info);
37!
63
    if (!status.ok()) {
37!
64
        return status;
×
65
    }
66
    return Status::OK();
37✔
67
}
111✔
68

69
DEVA_METHOD(CreateDir) {
39✔
70
    SPAN(span);
195!
71
    PLOG_DEBUG(("desc", "create_dir")("version", version)("index", index)("request", request->DebugString()));
39✔
72
    auto& path = request->path();
39!
73
    auto& dir_id = request->dir_id();
39!
74
    ObjectId dir_uuid = common::from_proto(dir_id);
39!
75
    auto status = create(path, dir_uuid, FileType::kDirectory);
39!
76
    if (!status.ok()) {
39!
77
        return status;
×
78
    }
79
    auto file_info = response->mutable_file_info();
39!
80
    common::to_proto(dir_uuid, file_info->mutable_file_id());
39!
81
    file_info->set_type(pain::proto::FileType::FILE_TYPE_DIRECTORY);
39!
82
    file_info->set_size(0);
39!
83
    file_info->set_atime(request->atime());
39!
84
    file_info->set_mtime(request->mtime());
39!
85
    file_info->set_ctime(request->ctime());
39!
86
    file_info->set_mode(request->mode());
39!
87
    file_info->set_uid(request->uid());
39!
88
    file_info->set_gid(request->gid());
39!
89
    status = update_file_info(dir_uuid, *file_info);
39!
90
    if (!status.ok()) {
39!
91
        return status;
×
92
    }
93
    return Status::OK();
39✔
94
}
117✔
95

96
DEVA_METHOD(ReadDir) {
2✔
97
    SPAN(span);
10!
98
    PLOG_DEBUG(("desc", "read_dir")("version", version)("index", index)("request", request->DebugString()));
2✔
99
    auto& path = request->path();
2!
100
    ObjectId parent_dir_uuid;
2✔
101
    FileType file_type = FileType::kNone;
2✔
102
    auto status = _namespace.lookup(path.c_str(), &parent_dir_uuid, &file_type);
2!
103
    if (!status.ok()) {
2!
104
        return status;
×
105
    }
106
    if (file_type != FileType::kDirectory) {
2!
107
        return Status(EINVAL, fmt::format("{} is not a directory", path.c_str()));
×
108
    }
109
    std::list<DirEntry> entries;
2✔
110
    _namespace.list(parent_dir_uuid, &entries);
2!
111
    for (auto& entry : entries) {
23✔
112
        auto dir_entry = response->add_entries();
21!
113
        common::to_proto(entry.inode, dir_entry->mutable_file_id());
21!
114
        dir_entry->set_type(static_cast<pain::proto::FileType>(entry.type));
21!
115
        dir_entry->set_name(std::move(entry.name));
21✔
116
    }
117
    return Status::OK();
2✔
118
}
6✔
119

120
DEVA_METHOD(RemoveFile) {
×
121
    SPAN(span);
×
122
    PLOG_INFO(("desc", "remove_file")("version", version)("index", index));
×
123
    return Status::OK();
×
124
}
×
125

126
DEVA_METHOD(SealFile) {
×
127
    SPAN(span);
×
128
    PLOG_INFO(("desc", "seal_file")("version", version)("index", index));
×
129
    return Status::OK();
×
130
}
×
131

132
DEVA_METHOD(CreateChunk) {
×
133
    SPAN(span);
×
134
    PLOG_INFO(("desc", "remove")("version", version)("index", index));
×
135
    return Status::OK();
×
136
}
×
137

138
DEVA_METHOD(CheckInChunk) {
×
139
    SPAN(span);
×
140
    PLOG_INFO(("desc", "seal")("version", version)("index", index));
×
141
    return Status::OK();
×
142
}
×
143

144
DEVA_METHOD(SealChunk) {
×
145
    SPAN(span);
×
146
    PLOG_INFO(("desc", "create_chunk")("version", version)("index", index));
×
147
    return Status::OK();
×
148
}
×
149

150
DEVA_METHOD(SealAndNewChunk) {
×
151
    SPAN(span);
×
152
    PLOG_INFO(("desc", "remove_chunk")("version", version)("index", index));
×
153
    return Status::OK();
×
154
}
×
155

156
DEVA_METHOD(GetFileInfo) {
1✔
157
    SPAN(span);
5!
158
    PLOG_INFO(("desc", "get_file_info")("version", version)("index", index));
1✔
159
    auto& path = request->path();
1!
160
    ObjectId file_uuid;
1✔
161
    FileType file_type = FileType::kNone;
1✔
162
    auto status = _namespace.lookup(path.c_str(), &file_uuid, &file_type);
1!
163
    if (!status.ok()) {
1!
164
        return status;
×
165
    }
166
    if (file_type != FileType::kFile) {
1!
167
        return Status(EINVAL, fmt::format("{} is not a file", path.c_str()));
×
168
    }
169
    proto::FileInfo file_info;
1!
170
    status = get_file_info(file_uuid, &file_info);
1!
171
    if (!status.ok()) {
1!
172
        return status;
×
173
    }
174
    response->mutable_file_info()->Swap(&file_info);
1!
175
    return Status::OK();
1✔
176
}
3✔
177

178
DEVA_METHOD(ManusyaHeartbeat) {
1✔
179
    SPAN(span);
5!
180
    PLOG_INFO(("desc", "manusya_heartbeat")("version", version)("index", index));
1✔
181
    auto& manusya_id = request->manusya_registration().manusya_id();
1!
182
    // auto& storage_info = request->manusya_registration().storage_info();
183
    // TODO: check cluster id
184

185
    UUID manusya_uuid(manusya_id.uuid().high(), manusya_id.uuid().low());
1!
186
    auto it = _manusya_descriptors.find(manusya_uuid);
1!
187
    if (it == _manusya_descriptors.end()) {
1!
188
        // new manusya
189
        PLOG_INFO(("desc", "new manusya")              //
1✔
190
                  ("manusya_uuid", manusya_uuid.str()) //
191
                  ("ip", manusya_id.ip())              //
192
                  ("port", manusya_id.port()));
193
        ManusyaDescriptor manusya_descriptor;
1✔
194
        manusya_descriptor.ip = manusya_id.ip();
1!
195
        manusya_descriptor.port = manusya_id.port();
1!
196
        manusya_descriptor.uuid = manusya_uuid;
1✔
197
        manusya_descriptor.is_alive = true;
1✔
198
        manusya_descriptor.update_heartbeat();
1✔
199
        _manusya_descriptors[manusya_uuid] = manusya_descriptor;
1!
200
    } else {
1✔
201
        auto& manusya_descriptor = it->second;
×
202
        manusya_descriptor.ip = manusya_id.ip();
×
203
        manusya_descriptor.port = manusya_id.port();
×
204
        manusya_descriptor.update_heartbeat();
×
205
    }
206
    return Status::OK();
2✔
207
}
3✔
208

209
DEVA_METHOD(ListManusya) {
2✔
210
    SPAN(span);
10!
211
    PLOG_INFO(("desc", "list_manusya")("version", version)("index", index));
2✔
212
    auto manusya_descriptors = response->mutable_manusya_descriptors();
2!
213
    for (auto& [_, manusya_descriptor] : _manusya_descriptors) {
3✔
214
        auto manusya_descriptor_proto = manusya_descriptors->Add();
1!
215
        manusya_descriptor_proto->mutable_manusya_id()->set_ip(manusya_descriptor.ip);
1!
216
        manusya_descriptor_proto->mutable_manusya_id()->set_port(manusya_descriptor.port);
1!
217
        manusya_descriptor_proto->mutable_manusya_id()->mutable_uuid()->set_high(manusya_descriptor.uuid.high());
1!
218
        manusya_descriptor_proto->mutable_manusya_id()->mutable_uuid()->set_low(manusya_descriptor.uuid.low());
1!
219
        manusya_descriptor_proto->mutable_storage_info()->set_cluster_id(manusya_descriptor.cluster_id);
1!
220
        manusya_descriptor_proto->set_is_alive(manusya_descriptor.is_alive);
1!
221
        manusya_descriptor_proto->set_last_heartbeat_time(manusya_descriptor.last_heartbeat_time);
1!
222
    }
223
    return Status::OK();
4✔
224
}
6✔
225

226
Status Deva::set_applied_index(int64_t index) {
76✔
227
    if (index <= _applied_index) {
76!
228
        PLOG_WARN(("desc", "index is applied already")("index", index));
×
229
        return Status::OK();
×
230
    }
231
    auto in_txn = common::TxnManager::instance().in_txn();
76!
232
    auto this_txn = _store->begin_txn();
76!
233
    auto txn = in_txn ? common::TxnManager::instance().get_txn_store() : this_txn.get();
76!
234
    if (txn == nullptr) {
76!
235
        return Status(EIO, "Failed to begin transaction");
×
236
    }
237
    auto status = txn->hset(_meta_key, _applied_index_key, std::to_string(index));
76!
238
    return status;
76!
239
    if (in_txn) {
240
        return Status::OK();
241
    }
242

243
    status = txn->commit();
244
    return status;
245
}
76✔
246

247
Status Deva::update_file_info(const ObjectId& id, const proto::FileInfo& file_info) {
76✔
248
    auto in_txn = common::TxnManager::instance().in_txn();
76!
249
    auto this_txn = _store->begin_txn();
76!
250
    auto txn = in_txn ? common::TxnManager::instance().get_txn_store() : this_txn.get();
76!
251
    if (txn == nullptr) {
76!
252
        return Status(EIO, "Failed to begin transaction");
×
253
    }
254
    auto status = txn->hset(_file_info_key, id.str(), file_info.SerializeAsString());
76!
255
    if (!status.ok()) {
76!
256
        return status;
×
257
    }
258
    if (in_txn) {
76!
259
        return Status::OK();
76✔
260
    }
261
    status = txn->commit();
×
262
    if (!status.ok()) {
×
263
        return status;
×
264
    }
265
    return status;
×
266
}
76✔
267

268
Status Deva::get_file_info(const ObjectId& id, proto::FileInfo* file_info) {
1✔
269
    std::string file_info_str;
1✔
270
    auto status = _store->hget(_file_info_key, id.str(), &file_info_str);
1!
271
    if (!status.ok()) {
1!
272
        return status;
×
273
    }
274
    auto ret = file_info->ParseFromString(file_info_str);
1!
275
    if (!ret) {
1!
276
        return Status(EIO, "Failed to parse file info");
×
277
    }
278
    return Status::OK();
1✔
279
}
1✔
280

281
Status Deva::remove_file_info(const ObjectId& id) {
×
282
    auto status = _store->hdel(_file_info_key, id.str());
×
283
    if (!status.ok()) {
×
284
        return status;
×
285
    }
286
    return Status::OK();
×
287
}
×
288

289
Status Deva::save_snapshot(std::string_view path, std::vector<std::string>* files) {
3✔
290
    return _store->check_point(path.data(), files);
3✔
291
}
292

293
Status Deva::load_snapshot(std::string_view path) {
3✔
294
    auto status = _store->recover(path.data());
3!
295
    if (!status.ok()) {
3!
296
        return status;
×
297
    }
298
    // get applied index
299
    std::string applied_index_str;
3✔
300
    status = _store->hget(_meta_key, _applied_index_key, &applied_index_str);
3!
301
    if (!status.ok()) {
3!
302
        return status;
×
303
    }
304
    _applied_index = std::stoll(applied_index_str);
3!
305
    return Status::OK();
3✔
306
}
3✔
307

308
} // namespace pain::deva
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc