Commit 13ee53a0 authored by Pavel Emelyanov's avatar Pavel Emelyanov

sockets: Save and restore fd flags for sockets

For regfiles this is done at open() time, for pipes thit is done with fcntl. Use
the same fcntl approach for sockets.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 827f1a2f
...@@ -248,6 +248,20 @@ int open_reg_by_id(u32 id) ...@@ -248,6 +248,20 @@ int open_reg_by_id(u32 id)
return open_fe_fd(fd); return open_fe_fd(fd);
} }
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
int set_fd_flags(int fd, int flags)
{
int old;
old = fcntl(fd, F_GETFL, 0);
if (old < 0)
return old;
flags = (SETFL_MASK & flags) | (old & ~SETFL_MASK);
return fcntl(fd, F_SETFL, flags);
}
static void transport_name_gen(struct sockaddr_un *addr, int *len, static void transport_name_gen(struct sockaddr_un *addr, int *len,
int pid, int fd) int pid, int fd)
{ {
......
...@@ -63,6 +63,7 @@ extern int prepare_shared_fdinfo(void); ...@@ -63,6 +63,7 @@ extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry); extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
extern int prepare_fs(int pid); extern int prepare_fs(int pid);
extern int open_reg_by_id(u32 id); extern int open_reg_by_id(u32 id);
int set_fd_flags(int fd, int flags);
extern int self_exe_fd; extern int self_exe_fd;
......
...@@ -99,6 +99,7 @@ struct unix_sk_entry { ...@@ -99,6 +99,7 @@ struct unix_sk_entry {
u8 state; u8 state;
u8 namelen; /* fits UNIX_PATH_MAX */ u8 namelen; /* fits UNIX_PATH_MAX */
u8 pad; u8 pad;
u32 flags;
u32 backlog; u32 backlog;
u32 peer; u32 peer;
u8 name[0]; u8 name[0];
...@@ -112,6 +113,7 @@ struct inet_sk_entry { ...@@ -112,6 +113,7 @@ struct inet_sk_entry {
u8 state; u8 state;
u16 src_port; u16 src_port;
u16 dst_port; u16 dst_port;
u32 flags;
u32 backlog; u32 backlog;
u32 src_addr[4]; u32 src_addr[4];
u32 dst_addr[4]; u32 dst_addr[4];
......
...@@ -217,20 +217,6 @@ static int recv_pipe_fd(struct pipe_info *pi) ...@@ -217,20 +217,6 @@ static int recv_pipe_fd(struct pipe_info *pi)
return fd; return fd;
} }
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
static int set_fd_flags(int fd, int flags)
{
int old;
old = fcntl(fd, F_GETFL, 0);
if (old < 0)
return old;
flags = (SETFL_MASK & flags) | (old & ~SETFL_MASK);
return fcntl(fd, F_SETFL, flags);
}
static int restore_pipe_data(int pfd, struct pipe_info *pi) static int restore_pipe_data(int pfd, struct pipe_info *pi)
{ {
int fd, size = 0, ret; int fd, size = 0, ret;
......
...@@ -325,6 +325,7 @@ static int dump_one_inet(struct socket_desc *_sk, struct fd_parms *p, ...@@ -325,6 +325,7 @@ static int dump_one_inet(struct socket_desc *_sk, struct fd_parms *p,
ie.src_port = sk->src_port; ie.src_port = sk->src_port;
ie.dst_port = sk->dst_port; ie.dst_port = sk->dst_port;
ie.backlog = sk->wqlen; ie.backlog = sk->wqlen;
ie.flags = p->flags;
memcpy(ie.src_addr, sk->src_addr, sizeof(u32) * 4); memcpy(ie.src_addr, sk->src_addr, sizeof(u32) * 4);
memcpy(ie.dst_addr, sk->dst_addr, sizeof(u32) * 4); memcpy(ie.dst_addr, sk->dst_addr, sizeof(u32) * 4);
...@@ -391,6 +392,7 @@ static int dump_one_unix(const struct socket_desc *_sk, struct fd_parms *p, ...@@ -391,6 +392,7 @@ static int dump_one_unix(const struct socket_desc *_sk, struct fd_parms *p,
ue.type = sk->type; ue.type = sk->type;
ue.state = sk->state; ue.state = sk->state;
ue.namelen = sk->namelen; ue.namelen = sk->namelen;
ue.flags = p->flags;
ue.backlog = sk->wqlen; ue.backlog = sk->wqlen;
ue.peer = sk->peer_ino; ue.peer = sk->peer_ino;
...@@ -998,6 +1000,9 @@ static int open_inet_sk(struct file_desc *d) ...@@ -998,6 +1000,9 @@ static int open_inet_sk(struct file_desc *d)
} }
} }
if (set_fd_flags(sk, ii->ie.flags))
return -1;
return sk; return sk;
err: err:
...@@ -1079,9 +1084,9 @@ void show_inetsk(int fd, struct cr_options *o) ...@@ -1079,9 +1084,9 @@ void show_inetsk(int fd, struct cr_options *o)
} }
} }
pr_msg("id %x family %s type %s proto %s state %s %s:%d <-> %s:%d\n", pr_msg("id %x family %s type %s proto %s state %s %s:%d <-> %s:%d flags %2x\n",
ie.id, skfamily2s(ie.family), sktype2s(ie.type), skproto2s(ie.proto), ie.id, skfamily2s(ie.family), sktype2s(ie.type), skproto2s(ie.proto),
skstate2s(ie.state), src_addr, ie.src_port, dst_addr, ie.dst_port); skstate2s(ie.state), src_addr, ie.src_port, dst_addr, ie.dst_port, ie.flags);
} }
out: out:
...@@ -1102,9 +1107,9 @@ void show_unixsk(int fd, struct cr_options *o) ...@@ -1102,9 +1107,9 @@ void show_unixsk(int fd, struct cr_options *o)
if (ret <= 0) if (ret <= 0)
goto out; goto out;
pr_msg("id %x type %s state %s namelen %4d backlog %4d peer %x", pr_msg("id %8x type %s state %s namelen %4d backlog %4d peer %8x flags %2x",
ue.id, sktype2s(ue.type), skstate2s(ue.state), ue.id, sktype2s(ue.type), skstate2s(ue.state),
ue.namelen, ue.backlog, ue.peer); ue.namelen, ue.backlog, ue.peer, ue.flags);
if (ue.namelen) { if (ue.namelen) {
BUG_ON(ue.namelen > sizeof(buf)); BUG_ON(ue.namelen > sizeof(buf));
...@@ -1208,6 +1213,9 @@ try_again: ...@@ -1208,6 +1213,9 @@ try_again:
if (restore_socket_queue(fle->fd, peer->ue.id)) if (restore_socket_queue(fle->fd, peer->ue.id))
return -1; return -1;
if (set_fd_flags(fle->fd, ui->ue.flags))
return -1;
cj = cj->next; cj = cj->next;
} }
...@@ -1269,6 +1277,11 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui) ...@@ -1269,6 +1277,11 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui)
if (restore_socket_queue(sk[1], ui->ue.id)) if (restore_socket_queue(sk[1], ui->ue.id))
return -1; return -1;
if (set_fd_flags(sk[0], ui->ue.flags))
return -1;
if (set_fd_flags(sk[1], peer->ue.flags))
return -1;
if (bind_unix_sk(sk[0], ui)) if (bind_unix_sk(sk[0], ui))
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment