int get_shmem_fd(int pid, VmaEntry *vi) { struct shmem_info *si; void *addr; int f; si = find_shmem_by_id(vi->shmid); pr_info("Search for 0x%016"PRIx64" shmem 0x%"PRIx64" %p/%d\n", vi->start, vi->shmid, si, si ? si->pid : -1); if (!si) { pr_err("Can't find my shmem 0x%016"PRIx64"\n", vi->start); return -1; } if (si->pid != pid) return shmem_wait_and_open(pid, si); if (si->fd != -1) return dup(si->fd); /* * The following hack solves problems: * vi->pgoff may be not zero in a target process. * This mapping may be mapped more then once. * The restorer doesn't have snprintf. * Here is a good place to restore content */ addr = mmap(NULL, si->size, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) { pr_err("Can't mmap shmid=0x%"PRIx64" size=%ld\n", vi->shmid, si->size); return -1; } if (restore_shmem_content(addr, si) < 0) { pr_err("Can't restore shmem content\n"); return -1; } f = open_proc_rw(getpid(), "map_files/%lx-%lx", (unsigned long) addr, (unsigned long) addr + si->size); munmap(addr, si->size); if (f < 0) return -1; si->fd = f; return f; }
int get_shmem_fd(int pid, VmaEntry *vi) { struct shmem_info *si; void *addr = MAP_FAILED; int f = -1; int flags; si = find_shmem_by_id(vi->shmid); pr_info("Search for 0x%016"PRIx64" shmem 0x%"PRIx64" %p/%d\n", vi->start, vi->shmid, si, si ? si->pid : -1); if (!si) { pr_err("Can't find my shmem 0x%016"PRIx64"\n", vi->start); return -1; } if (si->pid != pid) return shmem_wait_and_open(pid, si); if (si->fd != -1) return dup(si->fd); flags = MAP_SHARED; if (kdat.has_memfd) { f = sys_memfd_create("", 0); if (f < 0) { pr_perror("Unable to create memfd"); goto err; } if (ftruncate(f, si->size)) { pr_perror("Unable to truncate memfd"); goto err; } flags |= MAP_FILE; } else flags |= MAP_ANONYMOUS; /* * The following hack solves problems: * vi->pgoff may be not zero in a target process. * This mapping may be mapped more then once. * The restorer doesn't have snprintf. * Here is a good place to restore content */ addr = mmap(NULL, si->size, PROT_WRITE | PROT_READ, flags, f, 0); if (addr == MAP_FAILED) { pr_err("Can't mmap shmid=0x%"PRIx64" size=%ld\n", vi->shmid, si->size); goto err; } if (restore_shmem_content(addr, si) < 0) { pr_err("Can't restore shmem content\n"); goto err; } if (f == -1) { f = open_proc_rw(getpid(), "map_files/%lx-%lx", (unsigned long) addr, (unsigned long) addr + si->size); if (f < 0) goto err; } munmap(addr, si->size); si->fd = f; /* Send signal to slaves, that they can open fd for this shmem */ futex_inc_and_wake(&si->lock); /* * All other regions in this process will duplicate * the file descriptor, so we don't wait them. */ futex_wait_until(&si->lock, si->count - si->self_count + 1); return f; err: if (addr != MAP_FAILED) munmap(addr, si->size); close_safe(&f); return -1; }