Skip to content

Commit 3c67c0d

Browse files
committed
fix: proper support of vma mapping for restored posix semaphore
Signed-off-by: Brandon Smith <[email protected]>
1 parent 3aa881d commit 3c67c0d

File tree

6 files changed

+90
-17
lines changed

6 files changed

+90
-17
lines changed

criu/files.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,9 +1789,9 @@ static int collect_one_file(void *o, ProtobufCMessage *base, struct cr_img *i)
17891789
case FD_TYPES__PIDFD:
17901790
ret = collect_one_file_entry(fe, fe->pidfd->id, &fe->pidfd->base, &pidfd_cinfo);
17911791
break;
1792-
case FD_TYPES__POSIX_SEM:
1793-
ret = collect_one_file_entry(fe, fe->psm->fd_id, &fe->psm->base, &posix_sem_cinfo);
1794-
break;
1792+
case FD_TYPES__POSIX_SEM:
1793+
ret = collect_one_file_entry(fe, fe->psm->fd_id, &fe->psm->base, &posix_sem_cinfo);
1794+
break;
17951795
#ifdef CONFIG_HAS_LIBBPF
17961796
case FD_TYPES__BPFMAP:
17971797
ret = collect_one_file_entry(fe, fe->bpf->id, &fe->bpf->base, &bpfmap_cinfo);
@@ -1817,8 +1817,5 @@ int prepare_files(void)
18171817
init_dead_pidfd_hash();
18181818
if (collect_image(&files_cinfo))
18191819
return -1;
1820-
/* get posix semaphore info */
1821-
if (collect_image(&posix_sem_cinfo))
1822-
return -1;
18231820
return 0;
18241821
}

criu/include/files.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,5 +207,6 @@ extern struct collect_image_info posix_sem_cinfo;
207207

208208
extern bool should_dump_posix_semaphore(const char *path, const struct fd_parms *parms);
209209
extern int try_dump_posix_semaphore(const char *path, int lfd, u32 id, const struct fd_parms *parms);
210+
extern int open_posix_sem_vma(int pid, struct vma_area *vma);
210211

211212
#endif /* __CR_FILES_H__ */

criu/mem.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "prctl.h"
3333
#include "compel/infect-util.h"
3434
#include "pidfd-store.h"
35+
#include "files.h"
3536

3637
#include "protobuf.h"
3738
#include "images/pagemap.pb-c.h"
@@ -765,7 +766,11 @@ int prepare_mm_pid(struct pstree_item *i)
765766
ret = collect_filemap(vma);
766767
else if (vma_area_is(vma, VMA_AREA_SOCKET))
767768
ret = collect_socket_map(vma);
768-
else
769+
else if (vma_area_is(vma, VMA_AREA_POSIX_SEM)) {
770+
/* Set up vm_open function for POSIX semaphore VMAs */
771+
vma->vm_open = open_posix_sem_vma;
772+
ret = 0;
773+
} else
769774
ret = 0;
770775
if (ret)
771776
break;

criu/pie/restorer.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -881,21 +881,46 @@ static unsigned long restore_mapping(VmaEntry *vma_entry)
881881

882882
if (vma_entry_is(vma_entry, VMA_AREA_POSIX_SEM)) {
883883
/*
884-
* POSIX semaphore VMA are handled by the POSIX semaphore
885-
* restore code which recreates the semaphore and maps it properly.
886-
* create an anonymous mapping as a placeholder.
884+
* POSIX semaphore VMAs need special handling.
885+
* The semaphore file should already exist from FD restoration.
886+
* If the VMA doesn't have an fd, we'll try to find semaphore files -> Same node
887887
*/
888-
pr_info("Restoring POSIX semaphore VMA at %" PRIx64 "-%" PRIx64 "\n",
889-
vma_entry->start, vma_entry->end);
888+
void *addr;
889+
int sem_fd = (int)vma_entry->fd;
890890

891-
flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
892-
addr = sys_mmap(decode_pointer(vma_entry->start), vma_entry_len(vma_entry),
893-
prot | PROT_WRITE, flags, -1, 0);
891+
pr_info("Restoring POSIX semaphore VMA at %" PRIx64 "-%" PRIx64 " (fd=%d)\n",
892+
vma_entry->start, vma_entry->end, sem_fd);
893+
894+
if (sem_fd == -1) {
895+
return -1; // No semaphore file to restore
896+
}
897+
898+
/* Map the semaphore file to the original VMA address */
899+
addr = (void *)sys_mmap(decode_pointer(vma_entry->start),
900+
vma_entry_len(vma_entry),
901+
vma_entry->prot,
902+
vma_entry->flags | MAP_FIXED,
903+
sem_fd,
904+
vma_entry->pgoff);
905+
906+
if (addr == MAP_FAILED) {
907+
pr_err("Failed to map semaphore VMA: %p (fd=%d)\n", addr, sem_fd);
908+
return -1;
909+
}
910+
911+
if ((unsigned long)addr != vma_entry->start) {
912+
pr_err("VMA mapping failed: expected %" PRIx64 ", got %lx\n",
913+
vma_entry->start, (unsigned long)addr);
914+
return -1;
915+
}
916+
917+
pr_info("Successfully mapped semaphore VMA %" PRIx64 "-%" PRIx64 " (fd=%d)\n",
918+
vma_entry->start, vma_entry->end, sem_fd);
894919

895920
if ((vma_entry->fd != -1) && (vma_entry->status & VMA_CLOSE))
896921
sys_close(vma_entry->fd);
897922

898-
return addr;
923+
return vma_entry->start;
899924
}
900925

901926
/*

criu/posix-sem.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ static int posix_sem_open(struct file_desc *d, int *new_fd)
401401
sem_close(sem);
402402

403403
*new_fd = fd;
404+
404405
pr_info("Successfully restored POSIX semaphore %s with fd %d (cross-host migration)\n",
405406
pse->name, fd);
406407
return 0;
@@ -481,3 +482,45 @@ int try_dump_posix_semaphore(const char *path, int lfd, u32 id, const struct fd_
481482
return -1;
482483
}
483484
}
485+
486+
/*
487+
* Open POSIX semaphore for VMA mapping during restore
488+
* This function is called during VMA preparation to assign the correct
489+
* file descriptor to POSIX semaphore VMAs
490+
*/
491+
int open_posix_sem_vma(int pid, struct vma_area *vma)
492+
{
493+
struct file_desc *fd_desc;
494+
struct posix_sem_info *psi;
495+
int sem_fd;
496+
497+
pr_info("Opening POSIX semaphore VMA %" PRIx64 "-%" PRIx64 " (shmid=%" PRIx64 ")\n",
498+
vma->e->start, vma->e->end, vma->e->shmid);
499+
500+
/* Find the POSIX semaphore file descriptor by shmid */
501+
list_for_each_entry(psi, &posix_sem_list, d.fd_info_head) {
502+
if (psi->pse->ino == vma->e->shmid) {
503+
pr_info("Found matching POSIX semaphore %s for VMA (ino=%" PRIx64 ")\n",
504+
psi->pse->name, vma->e->shmid);
505+
506+
fd_desc = &psi->d;
507+
if (!inherited_fd(fd_desc, &sem_fd)) {
508+
if (posix_sem_open(fd_desc, &sem_fd) < 0) {
509+
pr_err("Failed to open POSIX semaphore %s\n", psi->pse->name);
510+
return -1;
511+
}
512+
}
513+
514+
pr_info("Assigned fd %d to POSIX semaphore VMA %" PRIx64 "-%" PRIx64 "\n",
515+
sem_fd, vma->e->start, vma->e->end);
516+
517+
vma->e->fd = sem_fd;
518+
vma->e->status |= VMA_CLOSE;
519+
return 0;
520+
}
521+
}
522+
523+
pr_err("No POSIX semaphore found for VMA %" PRIx64 "-%" PRIx64 " (shmid=%" PRIx64 ")\n",
524+
vma->e->start, vma->e->end, vma->e->shmid);
525+
return -1;
526+
}

criu/proc_parse.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,16 +623,18 @@ static int handle_vma(pid_t pid, struct vma_area *vma_area, const char *file_pat
623623
.mnt_id = vma_area->mnt_id,
624624
.fs_type = TMPFS_MAGIC
625625
}) == 1) {
626-
pr_info("Skipping refular file processing for POSIX semaphore VMA\n");
626+
pr_info("Skipping regular file processing for POSIX semaphore VMA\n");
627627
close_safe(vm_file_fd);
628628
vma_area->e->status = VMA_AREA_REGULAR | VMA_AREA_POSIX_SEM;
629+
vma_area->e->shmid = vma_area->vmst->st_ino;
629630
return 0;
630631
} else {
631632
pr_warn("Failed to handle as POSIX semaphore, continuing with regular file processing\n");
632633
}
633634
} else {
634635
pr_info("POSIX semaphore VMA mapping for non-deleted semaphore: %s\n", file_path);
635636
vma_area->e->status = VMA_AREA_REGULAR | VMA_AREA_POSIX_SEM;
637+
vma_area->e->shmid = vma_area->vmst->st_ino;
636638
}
637639
} else {
638640
/* link remap would be needed for this case */

0 commit comments

Comments
 (0)