vty: sub-divide talloc contexts and include them in talloc report

The VTY code makes so many allocations that a full report is
simply too long to provide any useful information.  So we sub-divide
it in multiple contexts, and report only one level deep at SIGURS1.

We also introduce SIGUSR2 for the full detailed VTY report.
diff --git a/openbsc/include/vty/command.h b/openbsc/include/vty/command.h
index 10a60ad..03b071f 100644
--- a/openbsc/include/vty/command.h
+++ b/openbsc/include/vty/command.h
@@ -356,4 +356,6 @@
 
 void print_version(const char *);
 
+extern void *tall_vty_cmd_ctx;
+
 #endif				/* _ZEBRA_COMMAND_H */
diff --git a/openbsc/include/vty/vector.h b/openbsc/include/vty/vector.h
index 00f0079..22a184d 100644
--- a/openbsc/include/vty/vector.h
+++ b/openbsc/include/vty/vector.h
@@ -59,4 +59,6 @@
 void *vector_lookup(vector, unsigned int);
 void *vector_lookup_ensure(vector, unsigned int);
 
+extern void *tall_vty_vec_ctx;
+
 #endif				/* _ZEBRA_VECTOR_H */
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 8792cc3..3122fae 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -138,6 +138,7 @@
 	}
 }
 
+extern void *tall_vty_ctx;
 static void signal_handler(int signal)
 {
 	fprintf(stdout, "signal %u received\n", signal);
@@ -153,8 +154,12 @@
 		/* in case of abort, we want to obtain a talloc report
 		 * and then return to the caller, who will abort the process */
 	case SIGUSR1:
+		talloc_report(tall_vty_ctx, stderr);
 		talloc_report_full(tall_bsc_ctx, stderr);
 		break;
+	case SIGUSR2:
+		talloc_report_full(tall_vty_ctx, stderr);
+		break;
 	default:
 		break;
 	}
@@ -219,6 +224,7 @@
 	signal(SIGINT, &signal_handler);
 	signal(SIGABRT, &signal_handler);
 	signal(SIGUSR1, &signal_handler);
+	signal(SIGUSR2, &signal_handler);
 	signal(SIGPIPE, SIG_IGN);
 
 	while (1) {
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
index 6372fb1..5b1dcb9 100644
--- a/openbsc/src/vty/command.c
+++ b/openbsc/src/vty/command.c
@@ -49,6 +49,8 @@
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/talloc.h>
 
+void *tall_vty_cmd_ctx;
+
 /* Command vector which includes some level of command lists. Normally
    each daemon maintains each own cmdvec. */
 vector cmdvec;
@@ -173,7 +175,7 @@
 		len += strlen(argv[i]) + 1;
 	if (!len)
 		return NULL;
-	p = str = _talloc_zero(tall_vty_ctx, len, "arvg_concat");
+	p = str = _talloc_zero(tall_vty_cmd_ctx, len, "arvg_concat");
 	for (i = shift; i < argc; i++) {
 		size_t arglen;
 		memcpy(p, argv[i], (arglen = strlen(argv[i])));
@@ -275,7 +277,7 @@
 		       *cp != '\0')
 			cp++;
 		strlen = cp - start;
-		token = _talloc_zero(tall_vty_ctx, strlen + 1, "make_strvec");
+		token = _talloc_zero(tall_vty_cmd_ctx, strlen + 1, "make_strvec");
 		memcpy(token, start, strlen);
 		*(token + strlen) = '\0';
 		vector_set(strvec, token);
@@ -331,7 +333,7 @@
 		cp++;
 
 	strlen = cp - start;
-	token = _talloc_zero(tall_vty_ctx, strlen + 1, "cmd_desc_str");
+	token = _talloc_zero(tall_vty_cmd_ctx, strlen + 1, "cmd_desc_str");
 	memcpy(token, start, strlen);
 	*(token + strlen) = '\0';
 
@@ -402,11 +404,11 @@
 
 		len = cp - sp;
 
-		token = _talloc_zero(tall_vty_ctx, len + 1, "cmd_make_descvec");
+		token = _talloc_zero(tall_vty_cmd_ctx, len + 1, "cmd_make_descvec");
 		memcpy(token, sp, len);
 		*(token + len) = '\0';
 
-		desc = talloc_zero(tall_vty_ctx, struct desc);
+		desc = talloc_zero(tall_vty_cmd_ctx, struct desc);
 		desc->cmd = token;
 		desc->str = cmd_desc_str(&dp);
 
@@ -1804,7 +1806,7 @@
 					if ((desc = vector_slot(descvec, j))) {
 						if ((string = cmd_entry_function(vector_slot(vline, index), desc->cmd)))
 							if (cmd_unique_string (matchvec, string))
-								vector_set (matchvec, talloc_strdup(tall_vty_ctx, string));
+								vector_set (matchvec, talloc_strdup(tall_vty_cmd_ctx, string));
 					}
 			}
 		}
@@ -1845,7 +1847,7 @@
 			if (len < lcd) {
 				char *lcdstr;
 
-				lcdstr = _talloc_zero(tall_vty_ctx, lcd + 1,
+				lcdstr = _talloc_zero(tall_vty_cmd_ctx, lcd + 1,
 						      "complete-lcdstr");
 				memcpy(lcdstr, matchvec->index[0], lcd);
 				lcdstr[lcd] = '\0';
@@ -2463,13 +2465,13 @@
 	config_file = host.config;
 
 	config_file_sav =
-	    _talloc_zero(tall_vty_ctx,
+	    _talloc_zero(tall_vty_cmd_ctx,
 			 strlen(config_file) + strlen(CONF_BACKUP_EXT) + 1,
 			 "config_file_sav");
 	strcpy(config_file_sav, config_file);
 	strcat(config_file_sav, CONF_BACKUP_EXT);
 
-	config_file_tmp = _talloc_zero(tall_vty_ctx, strlen(config_file) + 8,
+	config_file_tmp = _talloc_zero(tall_vty_cmd_ctx, strlen(config_file) + 8,
 					"config_file_tmp");
 	sprintf(config_file_tmp, "%s.XXXXXX", config_file);
 
@@ -2650,7 +2652,7 @@
 	if (host.name)
 		talloc_free(host.name);
 
-	host.name = talloc_strdup(tall_vty_ctx, argv[0]);
+	host.name = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
 	return CMD_SUCCESS;
 }
 
@@ -2685,7 +2687,7 @@
 			host.password = NULL;
 			if (host.password_encrypt)
 				talloc_free(host.password_encrypt);
-			host.password_encrypt = talloc_strdup(tall_vty_ctx, argv[1]);
+			host.password_encrypt = talloc_strdup(tall_vty_cmd_ctx, argv[1]);
 			return CMD_SUCCESS;
 		} else {
 			vty_out(vty, "Unknown encryption type.%s", VTY_NEWLINE);
@@ -2708,10 +2710,10 @@
 	if (host.encrypt) {
 		if (host.password_encrypt)
 			talloc_free(host.password_encrypt);
-		host.password_encrypt = talloc_strdup(tall_vty_ctx, zencrypt(argv[0]));
+		host.password_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(argv[0]));
 	} else
 #endif
-		host.password = talloc_strdup(tall_vty_ctx, argv[0]);
+		host.password = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
 
 	return CMD_SUCCESS;
 }
@@ -2744,7 +2746,7 @@
 
 			if (host.enable_encrypt)
 				talloc_free(host.enable_encrypt);
-			host.enable_encrypt = talloc_strdup(tall_vty_ctx, argv[1]);
+			host.enable_encrypt = talloc_strdup(tall_vty_cmd_ctx, argv[1]);
 
 			return CMD_SUCCESS;
 		} else {
@@ -2769,10 +2771,10 @@
 	if (host.encrypt) {
 		if (host.enable_encrypt)
 			talloc_free(host.enable_encrypt);
-		host.enable_encrypt = talloc_strdup(tall_vty_ctx, zencrypt(argv[0]));
+		host.enable_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(argv[0]));
 	} else
 #endif
-		host.enable = talloc_strdup(tall_vty_ctx, argv[0]);
+		host.enable = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
 
 	return CMD_SUCCESS;
 }
@@ -2816,12 +2818,12 @@
 	if (host.password) {
 		if (host.password_encrypt)
 			talloc_free(host.password_encrypt);
-		host.password_encrypt = talloc_strdup(tall_vty_ctx, zencrypt(host.password));
+		host.password_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(host.password));
 	}
 	if (host.enable) {
 		if (host.enable_encrypt)
 			talloc_free(host.enable_encrypt);
-		host.enable_encrypt = talloc_strdup(tall_vty_ctx, zencrypt(host.enable));
+		host.enable_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(host.enable));
 	}
 
 	return CMD_SUCCESS;
@@ -3095,7 +3097,7 @@
 	if (host.logfile)
 		talloc_free(host.logfile);
 
-	host.logfile = talloc_strdup(tall_vty_ctx, fname);
+	host.logfile = talloc_strdup(tall_vty_cmd_ctx, fname);
 
 	return CMD_SUCCESS;
 }
@@ -3285,7 +3287,7 @@
 {
 	if (host.motdfile)
 		talloc_free(host.motdfile);
-	host.motdfile = talloc_strdup(tall_vty_ctx, argv[0]);
+	host.motdfile = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
 
 	return CMD_SUCCESS;
 }
@@ -3313,7 +3315,7 @@
 /* Set config filename.  Called from vty.c */
 void host_config_set(const char *filename)
 {
-	host.config = talloc_strdup(tall_vty_ctx, filename);
+	host.config = talloc_strdup(tall_vty_cmd_ctx, filename);
 }
 
 void install_default(enum node_type node)
diff --git a/openbsc/src/vty/vector.c b/openbsc/src/vty/vector.c
index 371f71d..06e1aaa 100644
--- a/openbsc/src/vty/vector.c
+++ b/openbsc/src/vty/vector.c
@@ -27,10 +27,12 @@
 #include <openbsc/talloc.h>
 #include <memory.h>
 
+void *tall_vty_vec_ctx;
+
 /* Initialize vector : allocate memory and return vector. */
 vector vector_init(unsigned int size)
 {
-	vector v = talloc_zero(tall_vty_ctx, struct _vector);
+	vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
 	if (!v)
 		return NULL;
 
@@ -40,7 +42,7 @@
 
 	v->alloced = size;
 	v->active = 0;
-	v->index = _talloc_zero(tall_vty_ctx, sizeof(void *) * size,
+	v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
 				"vector_init:index");
 	if (!v->index) {
 		talloc_free(v);
@@ -68,7 +70,7 @@
 vector vector_copy(vector v)
 {
 	unsigned int size;
-	vector new = talloc_zero(tall_vty_ctx, struct _vector);
+	vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
 	if (!new)
 		return NULL;
 
@@ -76,7 +78,7 @@
 	new->alloced = v->alloced;
 
 	size = sizeof(void *) * (v->alloced);
-	new->index = _talloc_zero(tall_vty_ctx, size, "vector_copy:index");
+	new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
 	if (!new->index) {
 		talloc_free(new);
 		return NULL;
@@ -92,7 +94,7 @@
 	if (v->alloced > num)
 		return;
 
-	v->index = talloc_realloc_size(tall_vty_ctx, v->index,
+	v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
 				       sizeof(void *) * (v->alloced * 2));
 	memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
 	v->alloced *= 2;
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
index 788c7fd..2339bbd 100644
--- a/openbsc/src/vty/vty.c
+++ b/openbsc/src/vty/vty.c
@@ -1633,6 +1633,8 @@
 void vty_init()
 {
 	tall_vty_ctx = talloc_named_const(NULL, 0, "vty");
+	tall_vty_vec_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_vector");
+	tall_vty_cmd_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_command");
 
 	/* For further configuration read, preserve current directory. */
 	vty_save_cwd();