| 1331 | } |
| 1332 | |
| 1333 | static int |
| 1334 | sync_existing(struct rte_memseg_list *primary_msl, |
| 1335 | struct rte_memseg_list *local_msl, struct hugepage_info *hi, |
| 1336 | unsigned int msl_idx) |
| 1337 | { |
| 1338 | int ret, dir_fd; |
| 1339 | |
| 1340 | /* do not allow any page allocations during the time we're allocating, |
| 1341 | * because file creation and locking operations are not atomic, |
| 1342 | * and we might be the first or the last ones to use a particular page, |
| 1343 | * so we need to ensure atomicity of every operation. |
| 1344 | */ |
| 1345 | dir_fd = open(hi->hugedir, O_RDONLY); |
| 1346 | if (dir_fd < 0) { |
| 1347 | RTE_LOG(ERR, EAL, "%s(): Cannot open '%s': %s\n", __func__, |
| 1348 | hi->hugedir, strerror(errno)); |
| 1349 | return -1; |
| 1350 | } |
| 1351 | /* blocking writelock */ |
| 1352 | if (flock(dir_fd, LOCK_EX)) { |
| 1353 | RTE_LOG(ERR, EAL, "%s(): Cannot lock '%s': %s\n", __func__, |
| 1354 | hi->hugedir, strerror(errno)); |
| 1355 | close(dir_fd); |
| 1356 | return -1; |
| 1357 | } |
| 1358 | |
| 1359 | /* ensure all allocated space is the same in both lists */ |
| 1360 | ret = sync_status(primary_msl, local_msl, hi, msl_idx, true); |
| 1361 | if (ret < 0) |
| 1362 | goto fail; |
| 1363 | |
| 1364 | /* ensure all unallocated space is the same in both lists */ |
| 1365 | ret = sync_status(primary_msl, local_msl, hi, msl_idx, false); |
| 1366 | if (ret < 0) |
| 1367 | goto fail; |
| 1368 | |
| 1369 | /* update version number */ |
| 1370 | local_msl->version = primary_msl->version; |
| 1371 | |
| 1372 | close(dir_fd); |
| 1373 | |
| 1374 | return 0; |
| 1375 | fail: |
| 1376 | close(dir_fd); |
| 1377 | return -1; |
| 1378 | } |
| 1379 | |
| 1380 | static int |
| 1381 | sync_walk(const struct rte_memseg_list *msl, void *arg __rte_unused) |
no test coverage detected