mirror of
https://github.com/linux-msm/qrtr.git
synced 2026-04-09 23:00:03 +02:00
qrtr-ns: Move DEL_SERVER logic to server_del
When a server is disappearing, either from a DEL_SERVER, BYE or DEL_CLIENT message the same messages needs to be sent; to local observers and through broadcasts to remote nodes. So move the logic from the DEL_SERVER command handler to server_del, in order to invoke this regardless of reason for the server's disappearance. Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
124
src/ns.c
124
src/ns.c
@@ -194,6 +194,27 @@ static int service_announce_del(struct context *ctx,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int lookup_notify(struct context *ctx, struct sockaddr_qrtr *to,
|
||||
struct server *srv, bool new)
|
||||
{
|
||||
struct qrtr_ctrl_pkt pkt = {};
|
||||
int rc;
|
||||
|
||||
pkt.cmd = new ? QRTR_CMD_NEW_SERVER : QRTR_CMD_DEL_SERVER;
|
||||
if (srv) {
|
||||
pkt.server.service = cpu_to_le32(srv->service);
|
||||
pkt.server.instance = cpu_to_le32(srv->instance);
|
||||
pkt.server.node = cpu_to_le32(srv->node);
|
||||
pkt.server.port = cpu_to_le32(srv->port);
|
||||
}
|
||||
|
||||
rc = sendto(ctx->sock, &pkt, sizeof(pkt), 0,
|
||||
(struct sockaddr *)to, sizeof(*to));
|
||||
if (rc < 0)
|
||||
warn("send lookup result failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int annouce_servers(struct context *ctx, struct sockaddr_qrtr *sq)
|
||||
{
|
||||
struct map_entry *me;
|
||||
@@ -259,45 +280,38 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct server *server_del(unsigned int node_id, unsigned int port)
|
||||
static int server_del(struct context *ctx, struct node *node, unsigned int port)
|
||||
{
|
||||
struct lookup *lookup;
|
||||
struct list_item *li;
|
||||
struct map_item *mi;
|
||||
struct server *srv;
|
||||
struct node *node;
|
||||
|
||||
node = node_get(node_id);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
mi = map_get(&node->services, hash_u32(port));
|
||||
if (!mi)
|
||||
return NULL;
|
||||
return -ENOENT;
|
||||
|
||||
srv = container_of(mi, struct server, mi);
|
||||
map_remove(&node->services, srv->mi.key);
|
||||
|
||||
return srv;
|
||||
}
|
||||
/* Broadcast the removal of local services */
|
||||
if (srv->node == ctx->local_node)
|
||||
service_announce_del(ctx, &ctx->bcast_sq, srv);
|
||||
|
||||
static int lookup_notify(struct context *ctx, struct sockaddr_qrtr *to,
|
||||
struct server *srv, bool new)
|
||||
{
|
||||
struct qrtr_ctrl_pkt pkt = {};
|
||||
int rc;
|
||||
/* Announce the service's disappearance to observers */
|
||||
list_for_each(&ctx->lookups, li) {
|
||||
lookup = container_of(li, struct lookup, li);
|
||||
if (lookup->service && lookup->service != srv->service)
|
||||
continue;
|
||||
if (lookup->instance && lookup->instance != srv->instance)
|
||||
continue;
|
||||
|
||||
pkt.cmd = new ? QRTR_CMD_NEW_SERVER : QRTR_CMD_DEL_SERVER;
|
||||
if (srv) {
|
||||
pkt.server.service = cpu_to_le32(srv->service);
|
||||
pkt.server.instance = cpu_to_le32(srv->instance);
|
||||
pkt.server.node = cpu_to_le32(srv->node);
|
||||
pkt.server.port = cpu_to_le32(srv->port);
|
||||
lookup_notify(ctx, &lookup->sq, srv, false);
|
||||
}
|
||||
|
||||
rc = sendto(ctx->sock, &pkt, sizeof(pkt), 0,
|
||||
(struct sockaddr *)to, sizeof(*to));
|
||||
if (rc < 0)
|
||||
warn("send lookup result failed");
|
||||
return rc;
|
||||
free(srv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctrl_cmd_hello(struct context *ctx, struct sockaddr_qrtr *sq,
|
||||
@@ -316,6 +330,7 @@ static int ctrl_cmd_bye(struct context *ctx, struct sockaddr_qrtr *from)
|
||||
{
|
||||
struct qrtr_ctrl_pkt pkt;
|
||||
struct sockaddr_qrtr sq;
|
||||
struct node *local_node;
|
||||
struct map_entry *me;
|
||||
struct server *srv;
|
||||
struct node *node;
|
||||
@@ -325,18 +340,22 @@ static int ctrl_cmd_bye(struct context *ctx, struct sockaddr_qrtr *from)
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
map_clear(&node->services, server_mi_free);
|
||||
map_for_each(&node->services, me) {
|
||||
srv = map_iter_data(me, struct server, mi);
|
||||
|
||||
server_del(ctx, node, srv->port);
|
||||
}
|
||||
|
||||
/* Advertise the removal of this client to all local services */
|
||||
node = node_get(ctx->local_node);
|
||||
if (!node)
|
||||
local_node = node_get(ctx->local_node);
|
||||
if (!local_node)
|
||||
return 0;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
pkt.cmd = QRTR_CMD_BYE;
|
||||
pkt.client.node = from->sq_node;
|
||||
|
||||
map_for_each(&node->services, me) {
|
||||
map_for_each(&local_node->services, me) {
|
||||
srv = map_iter_data(me, struct server, mi);
|
||||
|
||||
sq.sq_family = AF_QIPCRTR;
|
||||
@@ -357,6 +376,7 @@ static int ctrl_cmd_del_client(struct context *ctx, unsigned node_id,
|
||||
{
|
||||
struct qrtr_ctrl_pkt pkt;
|
||||
struct sockaddr_qrtr sq;
|
||||
struct node *local_node;
|
||||
struct list_item *tmp;
|
||||
struct lookup *lookup;
|
||||
struct list_item *li;
|
||||
@@ -365,7 +385,7 @@ static int ctrl_cmd_del_client(struct context *ctx, unsigned node_id,
|
||||
struct node *node;
|
||||
int rc;
|
||||
|
||||
/* Remove any lookups for this client */
|
||||
/* Remove any lookups by this client */
|
||||
list_for_each_safe(&ctx->lookups, li, tmp) {
|
||||
lookup = container_of(li, struct lookup, li);
|
||||
if (lookup->sq.sq_node != node_id)
|
||||
@@ -378,24 +398,20 @@ static int ctrl_cmd_del_client(struct context *ctx, unsigned node_id,
|
||||
}
|
||||
|
||||
/* Remove the server belonging to this port*/
|
||||
srv = server_del(node_id, port);
|
||||
if (srv) {
|
||||
if (srv->node == ctx->local_node)
|
||||
service_announce_del(ctx, &ctx->bcast_sq, srv);
|
||||
|
||||
free(srv);
|
||||
}
|
||||
node = node_get(node_id);
|
||||
if (node)
|
||||
server_del(ctx, node, port);
|
||||
|
||||
/* Advertise the removal of this client to all local services */
|
||||
node = node_get(ctx->local_node);
|
||||
if (!node)
|
||||
local_node = node_get(ctx->local_node);
|
||||
if (!local_node)
|
||||
return 0;
|
||||
|
||||
pkt.cmd = QRTR_CMD_DEL_CLIENT;
|
||||
pkt.client.node = node_id;
|
||||
pkt.client.port = port;
|
||||
|
||||
map_for_each(&node->services, me) {
|
||||
map_for_each(&local_node->services, me) {
|
||||
srv = map_iter_data(me, struct server, mi);
|
||||
|
||||
sq.sq_family = AF_QIPCRTR;
|
||||
@@ -444,31 +460,13 @@ static int ctrl_cmd_del_server(struct context *ctx, unsigned int service,
|
||||
unsigned int instance, unsigned int node_id,
|
||||
unsigned int port)
|
||||
{
|
||||
struct lookup *lookup;
|
||||
struct list_item *li;
|
||||
struct server *srv;
|
||||
int rc = 0;
|
||||
struct node *node;
|
||||
|
||||
srv = server_del(node_id, port);
|
||||
if (!srv)
|
||||
return -EINVAL;
|
||||
node = node_get(node_id);
|
||||
if (!node)
|
||||
return -ENOENT;
|
||||
|
||||
if (srv->node == ctx->local_node)
|
||||
rc = service_announce_del(ctx, &ctx->bcast_sq, srv);
|
||||
|
||||
list_for_each(&ctx->lookups, li) {
|
||||
lookup = container_of(li, struct lookup, li);
|
||||
if (lookup->service && lookup->service != service)
|
||||
continue;
|
||||
if (lookup->instance && lookup->instance != instance)
|
||||
continue;
|
||||
|
||||
lookup_notify(ctx, &lookup->sq, srv, false);
|
||||
}
|
||||
|
||||
free(srv);
|
||||
|
||||
return rc;
|
||||
return server_del(ctx, node, port);
|
||||
}
|
||||
|
||||
static int ctrl_cmd_new_lookup(struct context *ctx, struct sockaddr_qrtr *from,
|
||||
|
||||
Reference in New Issue
Block a user