[CRIU] [PATCH 11/28] rst: new routines for restoring shared
files introduced
Andrew Vagin
avagin at parallels.com
Fri Mar 23 03:36:02 EDT 2012
On Thu, Mar 22, 2012 at 08:58:45PM +0300, Kinsbursky Stanislav wrote:
> From: Stanislav Kinsbursky <skinsbursky at openvz.org>
>
> These are slighlty reqirtten currently existent routines.
Why do we need new routines? What has been changed?
> Old ones will be
> removed later (simple replacement leads to unreadable patch).
I think you should split patched by another way
>
> Refresh of diff-rst-files-undump
> ---
> files.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 200 insertions(+), 0 deletions(-)
> diff --git a/files.c b/files.c
> index 6c14781..feff47b 100644
> --- a/files.c
> +++ b/files.c
> @@ -59,6 +59,15 @@ static struct fdinfo_desc *find_fd(u64 id)
> return NULL;
> }
>
> +struct file_recipient {
> + struct list_head list;
> + int pid;
> + int fd;
> + struct sockaddr_un saddr;
> + int sun_len;
> + u32 ready;
> +};
> +
> static int get_file_path(char *path, struct fdinfo_entry *fe, int fd)
> {
> if (read(fd, path, fe->len) != fe->len) {
> @@ -71,6 +80,34 @@ static int get_file_path(char *path, struct fdinfo_entry *fe, int fd)
> return 0;
> }
>
> +static int collect_fd_pid(int pid, struct fd_entry *fde)
> +{
> + struct file_info *fi;
> + struct file_recipient *recipient;
> +
> + pr_info("%d: Collect fd=%d type=%d id=%16lx\n",
> + pid, fde->fd, fde->type, fde->id);
> +
> + fi = file_search(fde->type, fde->id);
> + if (fi == NULL) {
> + pr_err("Failed to find shared file: type %d, id %ld\n\n", fde->type, fde->id);
> + return -1;
> + }
> +
> + recipient = xmalloc_shm(sizeof(*recipient));
> + if (!recipient)
> + return -ENOMEM;
> + recipient->pid = pid;
> + recipient->fd = fde->fd;
> + cr_wait_init(&recipient->ready);
> +
> + if (fi->pid < pid)
> + fi->pid = pid;
> +
> + list_add_tail(&recipient->list, &fi->recipients);
> + return 0;
> +}
> +
> static int collect_fd(int pid, struct fdinfo_entry *e)
> {
> int i;
> @@ -128,6 +165,17 @@ static int collect_fd(int pid, struct fdinfo_entry *e)
> return 0;
> }
>
> +static struct file_recipient *get_fd_recipient(struct file_info *fi,
> + int pid, int fd)
> +{
> + struct file_recipient *recipient = NULL;
> +
> + list_for_each_entry(recipient, &fi->recipients, list)
> + if ((recipient->pid == pid) && (recipient->fd == fd))
> + return recipient;
> + return NULL;
> +}
> +
> static int prepare_reg_files(void)
> {
> int reg_file_fd, ret = 0;
> @@ -270,6 +318,25 @@ static int restore_exe_early(struct fdinfo_entry *fe, int fd)
> return 0;
> }
>
> +static int receive_shared_fd(int pid, struct file_info *fi, struct fd_entry *fde)
> +{
> + int real_fd;
> +
> + if (fi->pid == pid)
> + return 0;
> +
> + pr_info("\t%d: Receive fd %d\n", pid, fde->fd);
> +
> + real_fd = recv_fd(fde->fd);
> + if (real_fd < 0) {
> + pr_err("Can't get fd %d\n", real_fd);
> + return -1;
> + }
> + close(fde->fd);
> +
> + return reopen_fd_as(fde->fd, real_fd);
> +}
> +
> struct fdinfo_list_entry *find_fdinfo_list_entry(int pid, int fd, struct fdinfo_desc *fi)
> {
> struct fdinfo_list_entry *fle;
> @@ -330,6 +397,139 @@ static int open_transport_fd(int pid, struct fdinfo_entry *fe,
> return 0;
> }
>
> +static int open_transport(int pid, int fd, struct file_info *fi)
> +{
> + struct file_recipient *recipient;
> + struct sockaddr_un *saddr;
> + int ret;
> + int sock;
> +
> + recipient = get_fd_recipient(fi, pid, fd);
> + if (!recipient) {
> + pr_err("Can't find recipient\n");
> + return -1;
> + }
> +
> + pr_info("\t%d: Found recipient: %p\n", pid, recipient);
> +
> + saddr = &recipient->saddr;
> + saddr->sun_family = AF_UNIX;
> + snprintf(saddr->sun_path, UNIX_PATH_MAX,
> + "X/crtools-%d-fd-%d", pid, fd);
> +
> + recipient->sun_len = SUN_LEN(saddr);
> + *saddr->sun_path = '\0';
> +
> + sock = socket(PF_UNIX, SOCK_DGRAM, 0);
> + if (sock < 0) {
> + pr_perror("Can't create socket");
> + return -1;
> + }
> +
> + ret = bind(sock, saddr, recipient->sun_len);
> + if (ret < 0) {
> + pr_perror("Can't bind unix socket %s", saddr->sun_path + 1);
> + return -1;
> + }
> +
> + ret = reopen_fd_as(recipient->fd, sock);
> + if (ret < 0)
> + return -1;
> +
> + cr_wait_set(&recipient->ready, pid);
> + pr_info("\t%d: Transport for fd %d ready (fi: %p, recipient: %p)\n",
> + pid, fd, fi, recipient);
> + return 0;
> +}
> +
> +static int send_fd_to_recipients(struct file_info *fi)
> +{
> + struct file_recipient *recipient, *tmp;
> + int sock;
> +
> + if (list_empty(&fi->recipients))
> + return 0;
> +
> + sock = socket(PF_UNIX, SOCK_DGRAM, 0);
> + if (sock < 0) {
> + pr_perror("Can't create socket");
> + return -1;
> + }
> +
> + pr_info("\t%d: Send fd %d\n", fi->pid, fi->fd);
> +
> + list_for_each_entry_safe(recipient, tmp, &fi->recipients, list) {
> + if (recipient->pid == fi->pid)
> + continue;
> + pr_info("\t%d: Wait pid's %d fd %d ready\n",
> + fi->pid, recipient->pid, recipient->fd);
> + cr_wait_while(&recipient->ready, 0);
> + pr_info("\t%d: Send to %s (fi: %p, recipient: %p)\n",
> + fi->pid, recipient->saddr.sun_path + 1, fi, recipient);
> + if (send_fd(sock, &recipient->saddr, recipient->sun_len, fi->fd) < 0) {
> + pr_perror("Can't send file descriptor");
> + return -1;
> + }
> + }
> + close(sock);
> + return 0;
> +}
> +
> +static int open_reg_file(struct file_info *fi, struct fd_entry *fde)
> +{
> + const struct file_entry *rfe = fi->rfe;
> +
> + pr_info("\t%d: Open fd %d (%s)\n", fi->pid, fde->fd, (char *)rfe->name);
> +
> + if (fi->fd != FD_ID_INVALID) {
> + if (dup2(fi->fd, fde->fd) != fde->fd)
> + return -1;
> + return 0;
> + }
> +
> + fi->fd = open((char *)rfe->name, rfe->flags);
> + if (fi->fd < 0) {
> + pr_perror("Can't open file %s", rfe->name);
> + return -1;
> + }
> + lseek(fi->fd, rfe->pos, SEEK_SET);
> +
> + if (reopen_fd_as(fde->fd, fi->fd) < 0)
> + return -1;
> +
> + fi->fd = fde->fd;
> +
> + return send_fd_to_recipients(fi);
> +}
> +
> +static int open_fd_and_send(int pid, struct file_info *fi, struct fd_entry *fde)
> +{
> + if (fi->pid != pid)
> + return 0;
> +
> + switch (fde->type) {
> + case FDINFO_REG:
> + return open_reg_file(fi, fde);
> + }
> +
> + pr_err("Failed to find shared file: type %d is not supported\n\n", fde->type);
> + return -1;
> +}
> +
> +static int open_fd_transport(int pid, struct file_info *fi, struct fd_entry *fde)
> +{
> + if (fi->pid == pid)
> + return 0;
> +
> + if (fde->type != FDINFO_REG)
> + return 0;
> +
> + pr_info("\t%d: Create transport for fd %d type %d id %ld\n", pid,
> + fde->fd, fde->type, fde->id);
> +
> + return open_transport(pid, fde->fd, fi);
> +}
> +
> static int open_fd(int pid, struct fdinfo_entry *fe,
> struct fdinfo_desc *fi, int fdinfo_fd)
> {
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list