summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/backup/backup.c9
-rw-r--r--accel-pppd/backup/backup.h1
-rw-r--r--accel-pppd/cli/std_cmd.c84
-rw-r--r--accel-pppd/cli/telnet.c2
-rw-r--r--accel-pppd/ctrl/ipoe/CMakeLists.txt5
-rw-r--r--accel-pppd/ctrl/ipoe/backup.c53
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c8
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h9
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe_netlink.c81
-rw-r--r--accel-pppd/include/ap_session.h2
-rw-r--r--accel-pppd/main.c115
-rw-r--r--accel-pppd/session.c21
-rw-r--r--drivers/ipoe/ipoe.c49
-rw-r--r--drivers/ipoe/ipoe.h1
14 files changed, 360 insertions, 80 deletions
diff --git a/accel-pppd/backup/backup.c b/accel-pppd/backup/backup.c
index d045f0cf..16349fc7 100644
--- a/accel-pppd/backup/backup.c
+++ b/accel-pppd/backup/backup.c
@@ -2,6 +2,7 @@
#include <string.h>
#include "triton.h"
+#include "log.h"
#include "events.h"
#include "ap_session.h"
#include "backup.h"
@@ -184,6 +185,8 @@ static void __restore_session(struct ap_session *ses)
}
}
+ log_ppp_info1("session restored\n");
+
if (ctrl)
ctrl->ctrl_start(ses);
else {
@@ -235,11 +238,17 @@ void backup_restore_fd()
void backup_restore(int internal)
{
struct backup_storage *storage;
+ struct backup_module *module;
list_for_each_entry(storage, &storage_list, entry) {
if (storage->restore)
storage->restore(internal);
}
+
+ list_for_each_entry(module, &module_list, entry) {
+ if (module->restore_complete)
+ module->restore_complete();
+ }
}
#endif
diff --git a/accel-pppd/backup/backup.h b/accel-pppd/backup/backup.h
index 39c4ed74..0037596a 100644
--- a/accel-pppd/backup/backup.h
+++ b/accel-pppd/backup/backup.h
@@ -52,6 +52,7 @@ struct backup_module
struct ap_session *(*ctrl_restore)(struct backup_mod *);
void (*ctrl_start)(struct ap_session *ses);
+ void (*restore_complete)(void);
};
struct backup_storage
diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c
index 0e1a7b21..01e01571 100644
--- a/accel-pppd/cli/std_cmd.c
+++ b/accel-pppd/cli/std_cmd.c
@@ -15,6 +15,8 @@
#include "log.h"
#include "memdebug.h"
+void core_restart(int);
+
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
struct timespec ts;
@@ -68,7 +70,7 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
cli_sendv(client, " timer_pending: %u\r\n", triton_stat.timer_pending);
//===========
- cli_send(client, "ppp:\r\n");
+ cli_send(client, "sessions:\r\n");
cli_sendv(client, " starting: %u\r\n", ap_session_stat.starting);
cli_sendv(client, " active: %u\r\n", ap_session_stat.active);
cli_sendv(client, " finishing: %u\r\n", ap_session_stat.finishing);
@@ -268,14 +270,27 @@ static void __terminate_hard2(struct ap_session *ses)
ap_session_terminate(ses, TERM_NAS_REBOOT, 1);
}
+static void terminate_all_sessions(int hard)
+{
+ struct ap_session *ses;
+
+ pthread_rwlock_rdlock(&ses_lock);
+ list_for_each_entry(ses, &ses_list, entry) {
+ if (hard)
+ triton_context_call(ses->ctrl->ctx, (triton_event_func)__terminate_hard2, ses);
+ else
+ triton_context_call(ses->ctrl->ctx, (triton_event_func)__terminate_soft2, ses);
+ }
+ pthread_rwlock_unlock(&ses_lock);
+}
+
static int shutdown_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
{
int hard = 0;
- struct ap_session *ses;
if (f_cnt == 2) {
if (!strcmp(f[1], "soft")) {
- ap_shutdown_soft();
+ ap_shutdown_soft(NULL);
return CLI_CMD_OK;
} else if (!strcmp(f[1], "hard"))
hard = 1;
@@ -286,16 +301,9 @@ static int shutdown_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
return CLI_CMD_SYNTAX;
}
- ap_shutdown_soft();
+ ap_shutdown_soft(NULL);
- pthread_rwlock_rdlock(&ses_lock);
- list_for_each_entry(ses, &ses_list, entry) {
- if (hard)
- triton_context_call(ses->ctrl->ctx, (triton_event_func)__terminate_hard2, ses);
- else
- triton_context_call(ses->ctrl->ctx, (triton_event_func)__terminate_soft2, ses);
- }
- pthread_rwlock_unlock(&ses_lock);
+ terminate_all_sessions(hard);
return CLI_CMD_OK;
}
@@ -328,11 +336,63 @@ static void reload_help(char * const *fields, int fields_cnt, void *client)
cli_send(client, "reload - reload config file\r\n");
}
+
+//==========================
+
+static void __do_restart(void)
+{
+ core_restart(0);
+ _exit(0);
+}
+
+static int restart_exec(const char *cmd, char * const *f, int f_cnt, void *cli)
+{
+ int hard;
+
+ if (f_cnt == 2) {
+ if (strcmp(f[1], "soft") == 0)
+ hard = 0;
+ else if (strcmp(f[1], "gracefully") == 0)
+ hard = 1;
+ else if (strcmp(f[1], "hard") == 0)
+ __do_restart();
+ else
+ return CLI_CMD_SYNTAX;
+ } else if (f_cnt == 1)
+ hard = 0;
+ else
+ return CLI_CMD_SYNTAX;
+
+#ifndef USE_BACKUP
+ hard = 1;
+#endif
+
+ if (hard) {
+ ap_shutdown_soft(__do_restart);
+ terminate_all_sessions(0);
+ } else {
+ core_restart(1);
+ _exit(0);
+ }
+
+ return CLI_CMD_OK;
+}
+
+static void restart_help(char * const *fields, int fields_cnt, void *client)
+{
+ cli_send(client, "restart [soft|gracefully|hard] - restart daemon\r\n");
+ cli_send(client, "\t\tsoft - restart daemon softly, e.g. keep existing connections if session backup is enabled (default)\r\n");
+ cli_send(client, "\t\tgracefully - terminate all connections then restart\r\n");
+ cli_send(client, "\t\thard - restart immediatly\r\n");
+}
+
+
static void init(void)
{
cli_register_simple_cmd2(show_stat_exec, show_stat_help, 2, "show", "stat");
cli_register_simple_cmd2(terminate_exec, terminate_help, 1, "terminate");
cli_register_simple_cmd2(reload_exec, reload_help, 1, "reload");
+ cli_register_simple_cmd2(restart_exec, restart_help, 1, "restart");
cli_register_simple_cmd2(shutdown_exec, shutdown_help, 1, "shutdown");
cli_register_simple_cmd2(exit_exec, exit_help, 1, "exit");
}
diff --git a/accel-pppd/cli/telnet.c b/accel-pppd/cli/telnet.c
index 543e32cc..5cb75c7a 100644
--- a/accel-pppd/cli/telnet.c
+++ b/accel-pppd/cli/telnet.c
@@ -555,6 +555,8 @@ static int serv_read(struct triton_md_handler_t *h)
continue;
}
+ fcntl(sock, F_SETFD, fcntl(sock, F_GETFD) | FD_CLOEXEC);
+
conn = _malloc(sizeof(*conn));
memset(conn, 0, sizeof(*conn));
conn->hnd.fd = sock;
diff --git a/accel-pppd/ctrl/ipoe/CMakeLists.txt b/accel-pppd/ctrl/ipoe/CMakeLists.txt
index 7be18cc0..fdcb3a49 100644
--- a/accel-pppd/ctrl/ipoe/CMakeLists.txt
+++ b/accel-pppd/ctrl/ipoe/CMakeLists.txt
@@ -5,6 +5,7 @@ SET(sources
dhcpv4.c
dhcpv4_options.c
ipoe_netlink.c
+ backup.c
)
IF (LUA)
@@ -17,10 +18,6 @@ IF (LUA)
SET(sources ${sources} lua.c lua_lpack.c)
ENDIF (LUA)
-IF (BACKUP)
- SET(sources ${sources} backup.c)
-ENDIF (BACKUP)
-
ADD_LIBRARY(ipoe SHARED ${sources})
IF (LUA)
TARGET_LINK_LIBRARIES(ipoe ${LUA_LIBRARIES})
diff --git a/accel-pppd/ctrl/ipoe/backup.c b/accel-pppd/ctrl/ipoe/backup.c
index b2d0c0c4..8347a4e5 100644
--- a/accel-pppd/ctrl/ipoe/backup.c
+++ b/accel-pppd/ctrl/ipoe/backup.c
@@ -4,6 +4,8 @@
#include <netinet/in.h>
#include <net/ethernet.h>
+#include "triton.h"
+#include "events.h"
#include "log.h"
#include "memdebug.h"
@@ -25,8 +27,13 @@
#define add_tag(id, data, size) if (!backup_add_tag(m, id, 0, data, size)) return -1;
-#define add_tag_int(id, data, size) if (!backup_add_tag(m, id, 1, data, size)) return -1;
+#define add_tag_i(id, data, size) if (!backup_add_tag(m, id, 1, data, size)) return -1;
+static LIST_HEAD(ds_list);
+
+static void restore_complete(void);
+
+#ifdef USE_BACKUP
static int session_save(struct ap_session *ses, struct backup_mod *m)
{
struct ipoe_session *conn = container_of(ses, typeof(*conn), ses);
@@ -44,9 +51,10 @@ static int session_save(struct ap_session *ses, struct backup_mod *m)
if (conn->agent_circuit_id)
add_tag(IPOE_TAG_AGENT_REMOTE_ID, conn->agent_remote_id->data, conn->agent_remote_id->len);
- //add_tag_int(IPOE_TAG_IFNAME, conn->serv->ifname, strlen(conn->serv->ifname) + 1);
add_tag(IPOE_TAG_IFNAME, conn->serv->ifname, strlen(conn->serv->ifname) + 1);
+ add_tag_i(IPOE_TAG_IFINDEX, &conn->ifindex, 4);
+
return 0;
}
@@ -74,6 +82,7 @@ static struct ap_session *ctrl_restore(struct backup_mod *m)
struct backup_tag *ifname = NULL;
int dlen = 0;
uint8_t *ptr;
+ struct ipoe_session_info *info;
//if (!m->data->internal)
// return NULL;
@@ -137,6 +146,9 @@ static struct ap_session *ctrl_restore(struct backup_mod *m)
case IPOE_TAG_AGENT_REMOTE_ID:
set_dhcpv4_opt(&ses->agent_remote_id, t, &ptr);
break;
+ case IPOE_TAG_IFINDEX:
+ ses->ifindex = *(uint32_t *)t->data;
+ break;
}
}
@@ -149,6 +161,16 @@ static struct ap_session *ctrl_restore(struct backup_mod *m)
list_add_tail(&ses->entry, &serv->sessions);
pthread_mutex_unlock(&serv->lock);
+ if (ses->ifindex != -1) {
+ list_for_each_entry(info, &ds_list, entry) {
+ if (info->ifindex == ses->ifindex) {
+ list_del(&info->entry);
+ _free(info);
+ break;
+ }
+ }
+ }
+
return &ses->ses;
}
@@ -157,11 +179,38 @@ static struct backup_module mod = {
.save = session_save,
.restore = session_restore,
.ctrl_restore = ctrl_restore,
+ .restore_complete = restore_complete,
};
+#endif
+
+static void dump_sessions(void)
+{
+ ipoe_nl_get_sessions(&ds_list);
+
+#ifndef USE_BACKUP
+ restore_complete();
+#endif
+}
+
+static void restore_complete(void)
+{
+ struct ipoe_session_info *info;
+
+ while (!list_empty(&ds_list)) {
+ info = list_entry(ds_list.next, typeof(*info), entry);
+ ipoe_nl_delete(info->ifindex);
+ list_del(&info->entry);
+ _free(info);
+ }
+}
static void init(void)
{
+ dump_sessions();
+
+#ifdef USE_BACKUP
backup_register_module(&mod);
+#endif
}
DEFINE_INIT(100, init);
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index fea61a8b..2f9cf129 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -166,7 +166,7 @@ static void ipoe_session_start(struct ipoe_session *ses)
if (ses->serv->opt_shared == 0)
strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
- else {
+ else if (ses->ifindex == -1) {
ses->ifindex = ipoe_nl_create(0, 0, ses->dhcpv4_request ? ses->serv->ifname : NULL, ses->hwaddr);
if (ses->ifindex == -1) {
log_ppp_error("ipoe: failed to create interface\n");
@@ -455,6 +455,9 @@ static void ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *p
struct ipoe_session *ses;
//struct dhcpv4_packet *reply;
+ if (ap_shutdown)
+ return;
+
pthread_mutex_lock(&serv->lock);
if (pack->msg_type == DHCPDISCOVER) {
ses = ipoe_session_lookup(serv, pack);
@@ -546,6 +549,9 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc
{
struct ipoe_session *ses;
+ if (ap_shutdown)
+ return NULL;
+
ses = mempool_alloc(ses_pool);
if (!ses) {
log_emerg("out of memery\n");
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index a2efd374..48bd631e 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -50,6 +50,14 @@ struct ipoe_session
int ifindex;
};
+struct ipoe_session_info
+{
+ struct list_head entry;
+ int ifindex;
+ uint32_t addr;
+ uint32_t peer_addr;
+};
+
#ifdef USE_LUA
int ipoe_lua_set_username(struct ipoe_session *, const char *func);
#endif
@@ -67,6 +75,7 @@ void ipoe_nl_delete_nets(void);
int ipoe_nl_create(uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr);
void ipoe_nl_delete(int ifindex);
int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr);
+void ipoe_nl_get_sessions(struct list_head *list);
#endif
diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
index 525dc0b3..74db52dc 100644
--- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c
+++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
@@ -21,6 +21,8 @@
#include "ipoe.h"
#include "if_ipoe.h"
+#include "memdebug.h"
+
#define PKT_ATTR_MAX 256
static struct rtnl_handle rth;
@@ -217,6 +219,84 @@ int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *i
return ret;
}
+static int dump_session(const struct sockaddr_nl *addr, struct nlmsghdr *n, void *arg)
+{
+ struct list_head *list = arg;
+ struct ipoe_session_info *info;
+ struct rtattr *tb[IPOE_ATTR_MAX + 1];
+ struct genlmsghdr *ghdr = NLMSG_DATA(n);
+ int len = n->nlmsg_len;
+ struct rtattr *attrs;
+
+ if (ghdr->cmd != IPOE_CMD_GET) {
+ log_error("ipoe: dump_session: got unexpected command %d\n", ghdr->cmd);
+ return 0;
+ }
+
+ len -= NLMSG_LENGTH(GENL_HDRLEN);
+ if (len < 0 ) {
+ log_error("ipoe: dump_session: wrong message length %i\n", len);
+ return -1;
+ }
+
+ attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN);
+ parse_rtattr(tb, IPOE_ATTR_MAX, attrs, len);
+
+ info = _malloc(sizeof(*info));
+ if (!info) {
+ log_emerg("out of memory\n");
+ return -1;
+ }
+
+ memset(info, 0, sizeof(*info));
+
+ if (tb[IPOE_ATTR_IFINDEX])
+ info->ifindex = *(uint32_t *)(RTA_DATA(tb[IPOE_ATTR_IFINDEX]));
+ else {
+ log_error("ipoe: dump_session: IPOE_ATTR_IFINDEX is absent\n");
+ _free(info);
+ return 0;
+ }
+
+ if (tb[IPOE_ATTR_ADDR])
+ info->addr = *(uint32_t *)(RTA_DATA(tb[IPOE_ATTR_ADDR]));
+
+ if (tb[IPOE_ATTR_PEER_ADDR])
+ info->peer_addr = *(uint32_t *)(RTA_DATA(tb[IPOE_ATTR_PEER_ADDR]));
+
+ list_add_tail(&info->entry, list);
+
+ return 0;
+}
+
+void ipoe_nl_get_sessions(struct list_head *list)
+{
+ struct nlmsghdr *nlh;
+ struct genlmsghdr *ghdr;
+ struct {
+ struct nlmsghdr n;
+ char buf[1024];
+ } req;
+
+ if (rth.fd == -1)
+ return;
+
+ nlh = &req.n;
+ nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+ nlh->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+ nlh->nlmsg_type = ipoe_genl_id;
+ nlh->nlmsg_seq = rth.dump = ++rth.seq;
+
+ ghdr = NLMSG_DATA(&req.n);
+ ghdr->cmd = IPOE_CMD_GET;
+
+ if (rtnl_send(&rth, (char *)nlh, nlh->nlmsg_len) < 0) {
+ log_emerg("ipoe: failed to send dump request: %s\n", strerror(errno));
+ return;
+ }
+
+ rtnl_dump_filter(&rth, dump_session, list, NULL, NULL);
+}
void ipoe_nl_delete(int ifindex)
{
@@ -378,7 +458,6 @@ static struct triton_md_handler_t up_hnd = {
static void init(void)
{
-
int mcg_id = genl_resolve_mcg(IPOE_GENL_NAME, IPOE_GENL_MCG_PKT, &ipoe_genl_id);
if (mcg_id == -1) {
log_warn("ipoe: unclassified packet handling is disabled\n");
diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h
index 075058c4..ab6f699c 100644
--- a/accel-pppd/include/ap_session.h
+++ b/accel-pppd/include/ap_session.h
@@ -109,6 +109,6 @@ void ap_session_activate(struct ap_session *ses);
void ap_session_ifup(struct ap_session *ses);
void ap_session_ifdown(struct ap_session *ses);
-void ap_shutdown_soft(void);
+void ap_shutdown_soft(void (*cb)(void));
#endif
diff --git a/accel-pppd/main.c b/accel-pppd/main.c
index 9e515564..14180605 100644
--- a/accel-pppd/main.c
+++ b/accel-pppd/main.c
@@ -27,7 +27,7 @@
static char *pid_file;
static char *conf_file;
static char *conf_dump;
-static char *exec_file;
+static sigset_t orig_set;
static void change_limits(void)
{
@@ -68,11 +68,12 @@ static void config_reload(int num)
triton_conf_reload(config_reload_notify);
}
-static void close_all_fd(void)
+/*static void close_all_fd(void)
{
DIR *dirp;
struct dirent ent, *res;
char path[128];
+ int fd;
sprintf(path, "/proc/%u/fd", getpid());
@@ -85,28 +86,30 @@ static void close_all_fd(void)
return;
if (!res)
break;
- close((unsigned long)atol(ent.d_name));
+
+ fd = atol(ent.d_name);
+ if (fd > 2)
+ close(fd);
}
closedir(dirp);
-}
+}*/
void core_restart(int soft)
{
char fname[128];
- int fd, n;
+ int fd, n, f = 0;
char cmdline[ARG_MAX];
- char *args[16];
+ char exe[PATH_MAX];
+ char *argv[16];
char *ptr = cmdline, *endptr;
- sigset_t set;
if (fork()) {
- close_all_fd();
+ //close_all_fd();
return;
}
- sigfillset(&set);
- pthread_sigmask(SIG_SETMASK, &set, NULL);
+ pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
sprintf(fname, "/proc/%i/cmdline", getpid());
@@ -116,65 +119,82 @@ void core_restart(int soft)
endptr = ptr + n;
n = 0;
- while (ptr < endptr) {
- args[n++] = ptr;
+ while (ptr < endptr && n < 14) {
+ if (strcmp(ptr, "--internal"))
+ argv[n++] = ptr;
+ else if (soft) {
+ f = 1;
+ argv[n++] = ptr;
+ }
+
while (ptr < endptr && *ptr++);
}
-
- args[n++] = NULL;
#ifdef USE_BACKUP
if (soft)
backup_restore_fd();
- else
#endif
- if (fork()) {
- close_all_fd();
- _exit(0);
- }
+ sprintf(exe, "/proc/%u/exe", getpid());
+ readlink(exe, exe, PATH_MAX);
+
+ if (!f)
+ argv[n++] = "--internal";
+
+ argv[n++] = NULL;
while (1) {
+ execv(exe, argv);
sleep(3);
- execv(args[0], args);
}
}
static void sigsegv(int num)
{
char cmd[PATH_MAX];
- char fname[PATH_MAX];
+ char fname[128];
+ char exec_file[PATH_MAX];
struct rlimit lim;
-#ifdef USE_BACKUP
- core_restart(1);
-#else
- core_restart(0);
-#endif
-
+ pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
+
if (conf_dump) {
FILE *f;
unsigned int t = time(NULL);
- sprintf(fname, "%s/cmd-%u", conf_dump, t);
+
+ chdir(conf_dump);
+
+ sprintf(fname, "cmd-%u", t);
f = fopen(fname, "w");
if (!f)
goto out;
fprintf(f, "thread apply all bt full\ndetach\nquit\n");
fclose(f);
- sprintf(cmd, "gdb -x %s %s %d > %s/dump-%u", fname, exec_file, getpid(), conf_dump, t);
+ sprintf(exec_file, "/proc/%u/exe", getpid());
+ readlink(exec_file, exec_file, PATH_MAX);
+
+ sprintf(cmd, "gdb -x %s %s %d > dump-%u", fname, exec_file, getpid(), t);
+
system(cmd);
- unlink(fname);
-
+
+ unlink(fname);
+ }
+
+out:
+#ifdef USE_BACKUP
+ core_restart(1);
+#else
+ core_restart(0);
+#endif
+
+ if (conf_dump) {
lim.rlim_cur = RLIM_INFINITY;
lim.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &lim);
-
- chdir(conf_dump);
}
-out:
abort();
}
@@ -185,15 +205,11 @@ int main(int argc, char **argv)
pid_t pid = 0;
struct sigaction sa;
int pagesize = sysconf(_SC_PAGE_SIZE);
-#ifdef USE_BACKUP
int internal = 0;
-#endif
if (argc < 2)
goto usage;
- exec_file = argv[0];
-
for(i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-d"))
goto_daemon = 1;
@@ -212,27 +228,18 @@ int main(int argc, char **argv)
conf_dump = memalign(pagesize, len);
strcpy(conf_dump, argv[++i]);
mprotect(conf_dump, len, PROT_READ);
- }
+ } else if (!strcmp(argv[i], "--internal"))
+ internal = 1;
}
if (!conf_file)
goto usage;
- if (pid_file) {
- FILE *f = fopen(pid_file, "r");
- if (f) {
- fscanf(f, "%u", &pid);
- fclose(f);
- }
-#ifdef USE_BACKUP
- internal = pid == getppid();
-#endif
- /*if (pid) {
- printf("%i %i %i\n", pid, getppid(), getpid());
- return 0;
- }*/
+ if (internal) {
+ while (getppid() != 1)
+ sleep(1);
}
-
+
if (triton_init(conf_file))
_exit(EXIT_FAILURE);
@@ -299,7 +306,7 @@ int main(int argc, char **argv)
sigdelset(&set, SIGUSR1);
sigdelset(&set, 35);
sigdelset(&set, 36);
- pthread_sigmask(SIG_SETMASK, &set, NULL);
+ pthread_sigmask(SIG_SETMASK, &set, &orig_set);
sigemptyset(&set);
//sigaddset(&set, SIGINT);
diff --git a/accel-pppd/session.c b/accel-pppd/session.c
index d24dcd75..0ca115c3 100644
--- a/accel-pppd/session.c
+++ b/accel-pppd/session.c
@@ -39,6 +39,8 @@ static long long unsigned seq;
struct ap_session_stat __export ap_session_stat;
+static void (*shutdown_cb)(void);
+
static void generate_sessionid(struct ap_session *ses);
void __export ap_session_init(struct ap_session *ses)
@@ -139,8 +141,12 @@ void __export ap_session_finished(struct ap_session *ses)
ses->backup->storage->free(ses->backup);
#endif
- if (ap_shutdown && !ap_session_stat.starting && !ap_session_stat.active && !ap_session_stat.finishing)
- kill(getpid(), SIGTERM);
+ if (ap_shutdown && !ap_session_stat.starting && !ap_session_stat.active && !ap_session_stat.finishing) {
+ if (shutdown_cb)
+ shutdown_cb();
+ else
+ kill(getpid(), SIGTERM);
+ }
}
void __export ap_session_terminate(struct ap_session *ses, int cause, int hard)
@@ -178,12 +184,17 @@ void __export ap_session_terminate(struct ap_session *ses, int cause, int hard)
ses->ctrl->terminate(ses, hard);
}
-void ap_shutdown_soft(void)
+void ap_shutdown_soft(void (*cb)(void))
{
ap_shutdown = 1;
+ shutdown_cb = cb;
- if (!ap_session_stat.starting && !ap_session_stat.active && !ap_session_stat.finishing)
- kill(getpid(), SIGTERM);
+ if (!ap_session_stat.starting && !ap_session_stat.active && !ap_session_stat.finishing) {
+ if (shutdown_cb)
+ shutdown_cb();
+ else
+ kill(getpid(), SIGTERM);
+ }
}
static void generate_sessionid(struct ap_session *ses)
diff --git a/drivers/ipoe/ipoe.c b/drivers/ipoe/ipoe.c
index d9ba4f4d..d5f52b3e 100644
--- a/drivers/ipoe/ipoe.c
+++ b/drivers/ipoe/ipoe.c
@@ -1226,6 +1226,50 @@ out_unlock:
return ret;
}
+static int fill_info(struct sk_buff *skb, struct ipoe_session *ses, u32 pid, u32 seq)
+{
+ void *hdr;
+
+ hdr = genlmsg_put(skb, pid, seq, &ipoe_nl_family, NLM_F_MULTI, IPOE_CMD_GET);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ NLA_PUT_U32(skb, IPOE_ATTR_IFINDEX, ses->dev->ifindex);
+ NLA_PUT_U32(skb, IPOE_ATTR_PEER_ADDR, ses->peer_addr);
+ NLA_PUT_U32(skb, IPOE_ATTR_ADDR, ses->addr);
+
+ return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+ genlmsg_cancel(skb, hdr);
+ return -EMSGSIZE;
+}
+
+static int ipoe_nl_cmd_dump_sessions(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct ipoe_session *ses;
+ int idx = 0, start_idx = cb->args[0];
+
+ down(&ipoe_wlock);
+
+ list_for_each_entry(ses, &ipoe_list2, entry2) {
+ if (idx > start_idx)
+ start_idx = 0;
+
+ if (idx++ < start_idx)
+ continue;
+
+ if (fill_info(skb, ses, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq) < 0)
+ break;
+ }
+
+ up(&ipoe_wlock);
+
+ cb->args[0] = idx;
+
+ return skb->len;
+}
+
static int ipoe_nl_cmd_add_net(struct sk_buff *skb, struct genl_info *info)
{
struct ipoe_network *n;
@@ -1314,6 +1358,11 @@ static struct genl_ops ipoe_nl_ops[] = {
.flags = GENL_ADMIN_PERM,
},
{
+ .cmd = IPOE_CMD_GET,
+ .dumpit = ipoe_nl_cmd_dump_sessions,
+ .policy = ipoe_nl_policy,
+ },
+ {
.cmd = IPOE_CMD_ADD_NET,
.doit = ipoe_nl_cmd_add_net,
.policy = ipoe_nl_policy,
diff --git a/drivers/ipoe/ipoe.h b/drivers/ipoe/ipoe.h
index 14833105..d40ac21a 100644
--- a/drivers/ipoe/ipoe.h
+++ b/drivers/ipoe/ipoe.h
@@ -8,6 +8,7 @@ enum {
IPOE_CMD_CREATE,
IPOE_CMD_DELETE,
IPOE_CMD_MODIFY,
+ IPOE_CMD_GET,
IPOE_CMD_ADD_NET,
IPOE_CMD_DEL_NET,
IPOE_REP_PKT,