Add support for UeCUPS_ResetAllState

This allows the controlling entity (testsuite) to reset all
state in the daemon.

Change-Id: I18c952b3874324a9efafb26b5f2c64f8396ff36a
This commit is contained in:
Harald Welte 2020-04-18 21:00:13 +02:00
parent 24557a76b7
commit 0174469247
2 changed files with 48 additions and 6 deletions

View File

@ -68,6 +68,14 @@ struct subprocess {
pid_t pid;
};
/* kill the specified subprocess and forget about it */
static void subprocess_destroy(struct subprocess *p, int signal)
{
kill(p->pid, signal);
llist_del(&p->list);
talloc_free(p);
}
/* Send JSON to a given client/connection */
static int cups_client_tx_json(struct cups_client *cc, json_t *jtx)
{
@ -446,6 +454,29 @@ static int cups_client_handle_start_program(struct cups_client *cc, json_t *spro
return 0;
}
static int cups_client_handle_reset_all_state(struct cups_client *cc, json_t *sprog)
{
struct gtp_daemon *d = cc->d;
struct gtp_tunnel *t, *t2;
struct subprocess *p, *p2;
json_t *jres;
pthread_rwlock_wrlock(&d->rwlock);
llist_for_each_entry_safe(t, t2, &d->gtp_tunnels, list) {
_gtp_tunnel_destroy(t);
}
pthread_rwlock_unlock(&d->rwlock);
/* no locking needed as this list is only used by main thread */
llist_for_each_entry_safe(p, p2, &d->subprocesses, list) {
subprocess_destroy(p, SIGKILL);
}
jres = gen_uecups_result("reset_all_state_res", "OK");
cups_client_tx_json(cc, jres);
return 0;
}
static int cups_client_handle_json(struct cups_client *cc, json_t *jroot)
{
@ -469,6 +500,8 @@ static int cups_client_handle_json(struct cups_client *cc, json_t *jroot)
rc = cups_client_handle_destroy_tun(cc, cmd);
} else if (!strcmp(key, "start_program")) {
rc = cups_client_handle_start_program(cc, cmd);
} else if (!strcmp(key, "reset_all_state")) {
rc = cups_client_handle_reset_all_state(cc, cmd);
} else {
LOGCC(cc, LOGL_NOTICE, "Unknown command '%s' received\n", key);
return -EINVAL;
@ -551,12 +584,10 @@ static int cups_client_closed_cb(struct osmo_stream_srv *conn)
struct subprocess *p, *p2;
/* kill + forget about all subprocesses of this client */
/* We need no locking here as the subprocess list is only used from the main thread */
llist_for_each_entry_safe(p, p2, &d->subprocesses, list) {
if (p->cups_client == cc) {
kill(p->pid, SIGKILL);
llist_del(&p->list);
talloc_free(p);
}
if (p->cups_client == cc)
subprocess_destroy(p, SIGKILL);
}
LOGCC(cc, LOGL_INFO, "UECUPS connection lost\n");

View File

@ -80,15 +80,26 @@ type record UECUPS_ProgramTermInd {
integer exit_code
};
type record UeCUPS_ResetAllState {
};
type record UeCUPS_ResetAllStateRes {
UECUPS_Result result
};
type union PDU_UECUPS {
UECUPS_CreateTun create_tun,
UECUPS_CreateTunRes create_tun_res,
UECUPS_DestroyTun destroy_tun,
UECUPS_DestroyTunRes destroy_tun_res,
UECUPS_StartProgram start_program,
UECUPS_StartProgramRes start_program_res,
UECUPS_ProgramTermInd program_term_ind
UECUPS_ProgramTermInd program_term_ind,
UeCUPS_ResetAllState reset_all_state,
UeCUPS_ResetAllStateRes reset_all_state_res
};