Commit 57eea3d3 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

sockets: Helper for binding unix socket

This one reads a name from image, does preparations for bind and calls bind.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent e1ed063f
...@@ -811,19 +811,17 @@ static int run_accept_jobs(void) ...@@ -811,19 +811,17 @@ static int run_accept_jobs(void)
return 0; return 0;
} }
static int open_unix_sk_dgram(int sk, struct unix_sk_entry *ue, int img_fd) static int bind_unix_sk(int sk, struct unix_sk_entry *ue, int img_fd)
{ {
if (ue->namelen) {
/*
* This is trivial socket bind() case,
* we don't have to wait for connect().
*/
struct unix_sk_listen *d;
struct sockaddr_un addr; struct sockaddr_un addr;
struct unix_sk_listen *e;
int ret; int ret;
if (!ue->namelen || ue->namelen >= UNIX_PATH_MAX) {
pr_err("Bad unix name len %d\n", ue->namelen);
goto err;
}
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
...@@ -844,85 +842,48 @@ static int open_unix_sk_dgram(int sk, struct unix_sk_entry *ue, int img_fd) ...@@ -844,85 +842,48 @@ static int open_unix_sk_dgram(int sk, struct unix_sk_entry *ue, int img_fd)
/* /*
* Just remember it and connect() if needed. * Just remember it and connect() if needed.
*/ */
d = xmalloc(sizeof(*d)); e = xmalloc(sizeof(*e));
if (!d) if (!e)
goto err; goto err;
memcpy(&d->addr, &addr, sizeof(d->addr)); memcpy(&e->addr, &addr, sizeof(e->addr));
d->addrlen = sizeof(addr.sun_family) + ue->namelen; e->addrlen = sizeof(addr.sun_family) + ue->namelen;
d->ino = ue->id; e->ino = ue->id;
d->type = SOCK_DGRAM; e->type = ue->type;
SK_HASH_LINK(unix_listen, d->ino, d);
}
if (ue->peer)
if (schedule_conn_job(CJ_DGRAM, ue))
goto err;
SK_HASH_LINK(unix_listen, e->ino, e);
return 0; return 0;
err: err:
return -1; return -1;
} }
static int open_unix_sk_stream(int sk, struct unix_sk_entry *ue, int img_fd) static int open_unix_sk_dgram(int sk, struct unix_sk_entry *ue, int img_fd)
{ {
int ret = -1; int ret = 0;
if (ue->state == TCP_LISTEN) { if (ue->namelen)
struct sockaddr_un addr; ret = bind_unix_sk(sk, ue, img_fd);
struct unix_sk_listen *e;
int ret;
/* if (!ret && ue->peer)
* Listen sockets are easiest ones -- simply ret = schedule_conn_job(CJ_DGRAM, ue);
* bind() and listen(), and that's all.
*/
if (!ue->namelen || ue->namelen >= UNIX_PATH_MAX) {
pr_err("Bad unix name len %d\n", ue->namelen);
goto err;
}
memset(&addr, 0, sizeof(addr)); return ret;
addr.sun_family = AF_UNIX; }
ret = read(img_fd, &addr.sun_path, ue->namelen); static int open_unix_sk_stream(int sk, struct unix_sk_entry *ue, int img_fd)
if (ret != ue->namelen) { {
pr_err("Error reading socket name from image (%d)", ret); int ret;
goto err;
}
if (addr.sun_path[0] != '\0') if (ue->state == TCP_LISTEN) {
unlink(addr.sun_path); ret = bind_unix_sk(sk, ue, img_fd);
if (bind(sk, (struct sockaddr *)&addr, if (ret < 0)
sizeof(addr.sun_family) + ue->namelen) < 0) { goto out;
pr_perror("Can't bind socket");
goto err;
}
if (listen(sk, ue->backlog) < 0) { ret = listen(sk, ue->backlog);
if (ret < 0) {
pr_perror("Can't listen socket"); pr_perror("Can't listen socket");
goto err; goto out;
} }
/*
* Collect listening sockets here, we will
* need them to resolve in-flight connections
* names.
*/
e = xzalloc(sizeof(*e));
if (!e)
goto err;
SK_HASH_LINK(unix_listen, ue->id, e);
memcpy(&e->addr, &addr, sizeof(e->addr));
e->addrlen = sizeof(e->addr.sun_family) + ue->namelen;
e->ino = ue->id;
e->type = SOCK_STREAM;
dprintk("\tCollected listening socket %d\n", ue->id);
} else if (ue->state == TCP_ESTABLISHED) { } else if (ue->state == TCP_ESTABLISHED) {
/* /*
...@@ -943,37 +904,35 @@ static int open_unix_sk_stream(int sk, struct unix_sk_entry *ue, int img_fd) ...@@ -943,37 +904,35 @@ static int open_unix_sk_stream(int sk, struct unix_sk_entry *ue, int img_fd)
* Will become a server * Will become a server
*/ */
ret = -1;
prep_conn_addr(ue->id, &addr, &len); prep_conn_addr(ue->id, &addr, &len);
if (bind(sk, (struct sockaddr *)&addr, len) < 0) { if (bind(sk, (struct sockaddr *)&addr, len) < 0) {
pr_perror("Can't bind socket"); pr_perror("Can't bind socket");
goto err; goto out;
} }
if (listen(sk, 1) < 0) { if (listen(sk, 1) < 0) {
pr_perror("Can't listen socket"); pr_perror("Can't listen socket");
goto err; goto out;
} }
aj = xmalloc(sizeof(*aj)); aj = xmalloc(sizeof(*aj));
if (aj == NULL) if (aj == NULL)
goto err; goto out;
aj->fd = ue->fd; aj->fd = ue->fd;
aj->next = accept_jobs; aj->next = accept_jobs;
accept_jobs = aj; accept_jobs = aj;
unix_show_job("Sched acc", ue->fd, ue->id); unix_show_job("Sched acc", ue->fd, ue->id);
} else { ret = 0;
if (schedule_conn_job((ue->flags & USK_INFLIGHT) ? } else
CJ_STREAM_INFLIGHT : CJ_STREAM, ue)) ret = schedule_conn_job((ue->flags & USK_INFLIGHT) ?
goto err; CJ_STREAM_INFLIGHT : CJ_STREAM, ue);
}
} else { } else {
pr_err("Unknown state %d\n", ue->state); pr_err("Unknown state %d\n", ue->state);
goto err; ret = -1;
} }
out:
ret = 0;
err:
return ret; return ret;
} }
......
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