[lxc-devel] [lxc/master] skeleton for error handling #723

AustinReichert on Github lxc-bot at linuxcontainers.org
Mon Dec 4 23:06:28 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 2440 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171204/efb9fa3a/attachment.bin>
-------------- next part --------------
From e395e4f5e8f8b25fb1217e04543fe446604180f3 Mon Sep 17 00:00:00 2001
From: Yasmine Zakout <yazakout at cs.utexas.edu>
Date: Wed, 29 Nov 2017 13:52:30 -0600
Subject: [PATCH 1/6] Added notes for macros in the tools dir.  lxc_error.h
 contains the macros and the line numbers they should be replacing, error.txt
 contains all the results from my grep.

---
 src/lxc/tools/error.txt   | 84 +++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/tools/lxc_error.h | 61 ++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+)
 create mode 100644 src/lxc/tools/error.txt
 create mode 100644 src/lxc/tools/lxc_error.h

diff --git a/src/lxc/tools/error.txt b/src/lxc/tools/error.txt
new file mode 100644
index 000000000..92e3fdba9
--- /dev/null
+++ b/src/lxc/tools/error.txt
@@ -0,0 +1,84 @@
+lxc_copy.c:518:		ERROR("Error: Renaming container %s to %s failed\n", c->name, newname);
+lxc_copy.c:866:		SYSERROR("Failed to set close-on-exec on file descriptor.");
+lxc_create.c:127:	ERROR("Error executing %s -h", path);
+lxc_create.c:329:		ERROR("Error creating container %s", c->name);
+lxc_destroy.c:236:			SYSERROR("failed to allocate memory");
+lxc_destroy.c:243:			ERROR("could not read %s", path);
+lxc_device.c:68:		SYSERROR("failed to fork task.");
+lxc_device.c:76:			ERROR("failed to enter netns of container.");
+lxc_device.c:82:			ERROR("failed to get interfaces list");
+lxc_device.c:109:		ERROR("%s must be run as root", argv[0]);
+lxc_device.c:135:		ERROR("%s doesn't exist", my_args.name);
+lxc_device.c:142:			ERROR("Failed to load rcfile");
+lxc_device.c:147:			ERROR("Out of memory setting new config filename");
+lxc_device.c:153:		ERROR("Container %s is not running.", c->name);
+lxc_device.c:158:		ERROR("Error: no command given (Please see --help output)");
+lxc_device.c:176:			ERROR("Failed to add %s to %s.", dev_name, c->name);
+lxc_device.c:187:			ERROR("Failed to del %s from %s.", dev_name, c->name);
+lxc_device.c:192:		ERROR("Error: Please use add or del (Please see --help output)");
+lxc_execute.c:149:		ERROR("Failed to create lxc_container");
+lxc_execute.c:156:			ERROR("Failed to load rcfile");
+lxc_execute.c:162:			ERROR("Out of memory setting new config filename");
+lxc_execute.c:170:			ERROR("missing command to execute!");
+lxc_execute.c:193:		ERROR("Failed run an application inside container");
+lxc_freeze.c:84:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
+lxc_freeze.c:91:			ERROR("Failed to load rcfile");
+lxc_freeze.c:97:			ERROR("Out of memory setting new config filename");
+lxc_freeze.c:104:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
+lxc_freeze.c:110:		ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name);
+lxc_init.c:102:		ERROR("Please specify a command to execute");
+lxc_init.c:171:			SYSERROR("Failed to change signal action");
+lxc_init.c:196:			SYSERROR("Failed to set signal mask");
+lxc_init.c:210:		ERROR("%s - Failed to exec \"%s\"", strerror(errno), my_args.argv[0]);
+lxc_init.c:224:		SYSERROR("Failed to set signal mask");
+lxc_init.c:274:			ERROR("%s - Failed to wait on child %d",
+lxc_monitor.c:126:				ERROR("Unable to open monitor on path: %s", my_args.lxcpath[i]);
+lxc_monitor.c:131:				SYSERROR("Unable to close monitor on path: %s", my_args.lxcpath[i]);
+lxc_monitor.c:144:		ERROR("failed to allocate memory");
+lxc_monitor.c:149:		ERROR("Name too long");
+lxc_monitor.c:154:		ERROR("failed to compile the regex '%s'", my_args.name);
+lxc_monitor.c:160:		SYSERROR("out of memory");
+lxc_snapshot.c:211:		ERROR("Error creating a snapshot");
+lxc_snapshot.c:230:		ERROR("Error destroying snapshot %s", snapname);
+lxc_snapshot.c:244:		ERROR("Error listing snapshots");
+lxc_snapshot.c:284:		ERROR("Error restoring snapshot %s", args->snapname);
+lxc_start.c:71:				SYSERROR("failed to create '%s'", path);
+lxc_start.c:80:			SYSERROR("failed to get the real path of '%s'", path);
+lxc_start.c:215:			ERROR("Failed to create lxc_container");
+lxc_start.c:220:			ERROR("Failed to load rcfile");
+lxc_start.c:226:			ERROR("Out of memory setting new config filename");
+lxc_start.c:234:			SYSERROR("failed to allocate memory");
+lxc_start.c:246:			ERROR("Failed to create lxc_container");
+lxc_start.c:263:		ERROR("Container is already running.");
+lxc_start.c:279:		ERROR("Executing '/sbin/init' with no configuration file may crash the host");
+lxc_start.c:285:			ERROR("failed to ensure pidfile '%s'", my_args.pidfile);
+lxc_start.c:325:		ERROR("The container failed to start.");
+lxc_start.c:327:			ERROR("To get more details, run the container in foreground mode.");
+lxc_start.c:328:		ERROR("Additional information can be obtained by setting the "
+lxc_top.c:152:		ERROR("stdin is not a tty");
+lxc_top.c:157:		SYSERROR("failed to get current terminal settings");
+lxc_top.c:171:		ERROR("failed to set new terminal settings");
+lxc_top.c:236:		ERROR("unable to read cgroup item %s", item);
+lxc_top.c:255:		ERROR("unable to read cgroup item %s", item);
+lxc_top.c:311:		ERROR("unable to read cgroup item %s", item);
+lxc_top.c:540:			ERROR("cannot alloc mem");
+lxc_top.c:546:				ERROR("cannot alloc mem");
+lxc_top.c:566:		ERROR("failed to setup terminal");
+lxc_top.c:576:		ERROR("failed to create mainloop");
+lxc_top.c:582:		ERROR("failed to add stdin handler");
+lxc_unfreeze.c:83:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
+lxc_unfreeze.c:88:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
+lxc_unfreeze.c:96:			ERROR("Failed to load rcfile");
+lxc_unfreeze.c:102:			ERROR("Out of memory setting new config filename");
+lxc_unfreeze.c:109:		ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name);
+lxc_unshare.c:84:			ERROR("invalid username %s", name);
+lxc_unshare.c:91:			ERROR("invalid uid %u", *uid);
+lxc_unshare.c:122:			ERROR("failed to set hostname %s: %s", want_hostname, strerror(errno));
+lxc_unshare.c:128:		ERROR("failed to set uid %d: %s", uid, strerror(errno));
+lxc_unshare.c:134:	ERROR("failed to exec: '%s': %s", args[0], strerror(errno));
+lxc_unshare.c:192:		ERROR("a command to execute in the new namespace is required");
+lxc_unshare.c:232:		ERROR("-i <interfacename> needs -s NETWORK option");
+lxc_unshare.c:237:		ERROR("-H <hostname> needs -s UTSNAME option");
+lxc_unshare.c:242:		ERROR("-M needs -s MOUNT option");
+lxc_unshare.c:248:		ERROR("failed to clone");
+lxc_unshare.c:263:		ERROR("failed to wait for '%d'", pid);
diff --git a/src/lxc/tools/lxc_error.h b/src/lxc/tools/lxc_error.h
new file mode 100644
index 000000000..c58f0ecd8
--- /dev/null
+++ b/src/lxc/tools/lxc_error.h
@@ -0,0 +1,61 @@
+// These should be organized in a way that makes more sense
+
+// lxc_copy.c: 518; lxc_unshare.c: 248
+#define LXC_CLONE_ERR 1 
+//lxc_copy.c: 866
+#define LXC_FD_ERR 2
+//lxc_create.c:127, lxc_init.c: 210; lxc_unshare.c: 134
+#define LXC_EXEC_ERR 3
+//lxc_create.c:329; lxc_execute.c: 149; lxc_start.c: 215; 246
+#define LXC_CREATE_ERR 4
+//lxc_destroy.c: 236; lxc_monitor.c: 144; lxc_start.c:234; lxc_top.c: 540, 546
+// maybe combined with OOM, idk what else can go wrong with calloc
+#define LXC_MEM_ALLOC_ERR 5
+//lxc_destroy.c: 243
+#define LXC_FILE_READ_ERR 6
+//lxc_device.c: 68
+#define LXC_FORK_ERR 7
+//lxc_device.c: 76
+#define LXC_NS_ERR 8
+//lxc_device.c: 82
+#define LXC_NETIF_ERR 9
+//lxc_device.c: 109; lxc_freeze.c: 104; lxc_unfreeze.c: 83
+#define LXC_INSUF_PRIV_ERR 10
+//lxc_device.c: 135; lxc_freeze.c: 84; lxc_unfreeze.c: 83
+#define LXC_CONT_EXIST_ERR 11
+//lxc_device.c: 142; lxc_execute.c:156; lxc_freeze.c: 91; lxc_start.c: 220; lxc_unfreeze.c: 96
+#define LXC_RCFILE_ERR 12
+//lxc_device.c: 147; lxc_execute.c: 162; lxc_freeze.c: 97; lxc_monitor.c: 160; lxc_start.c: 246; lxc_unfreeze.c: 102
+#define LXC_OOM_ERR 13
+//lxc_device.c: 176, 187
+#define LXC_DEVICE_ERR 14
+//lxc_device.c: 192; lxc_execute.c: 170; lxc_init.c: 102; lxc_monitor.c: 149, 154; lxc_start.c: 263, 279 285; lxc_unshare.c: 84, 91, 192, 232, 237, 242
+#define LXC_ARGS_INVAL 15
+//lxc_execute.c: 193
+#define LXC_APP_ERR 16
+//lxc_freeze.c: 110
+#define LXC_FREEZE_ERR 17
+//lxc_init.c: 171
+#define LXC_SIGACTION_ERR 18
+//lxc_init.c: 196, 224
+#define LXC_SIGMSK_ERR 19
+// lxc_init.c: 274; lxc_unshare.c: 263
+#define LXC_WAIT_ERR 20
+//lxc_monitor.c: 126, 131
+#define LXC_MONITOR_ERR 21
+//lxc_snapshot.c:211, 230, 244, 284
+#define LXC_SNAPSHOT_ERR 22
+//lxc_start.c: 71, 80
+#define LXC_PATH_ERR 23
+//lxc_start.c: 325
+#define LXC_START_ERR 24
+//lxc_top.c: 152; 157, 566, 576, 582
+#define LXC_TOP_ERR 25
+//lxc_top.c: 236, 255, 311
+#define LXC_READ_CGROUP_ERR 26
+//lxc_unfreeze.c: 109
+#define LXC_UNFREEZE_ERR 27
+//lxc_unshared.c: 128
+#define LXC_UID_ERR 28
+//lxc_unshare.c:122
+#define LXC_HOSTNAME_ERR 29

From 5d284cb5921e8db8fdcfe6f9c8ed7c8d7ef6b318 Mon Sep 17 00:00:00 2001
From: AustinReichert <austinskyreichert at utexas.edu>
Date: Thu, 30 Nov 2017 21:22:42 -0600
Subject: [PATCH 2/6] lxc_error.c error concatenation working

Signed-off-by: AustinReichert <austinskyreichert at utexas.edu>
---
 src/lxc/lxc_error.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 src/lxc/lxc_error.c

diff --git a/src/lxc/lxc_error.c b/src/lxc/lxc_error.c
new file mode 100644
index 000000000..4756f7139
--- /dev/null
+++ b/src/lxc/lxc_error.c
@@ -0,0 +1,109 @@
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+//#include "config.h"
+
+#include <errno.h>
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+
+//#include <lxc/lxccontainer.h>
+
+/*#include "attach.h"
+#include "arguments.h"
+#include "caps.h"
+#include "conf.h"
+#include "confile.h"
+#include "console.h"
+#include "log.h"
+#include "list.h"
+#include "mainloop.h"
+#include "utils.h"
+
+#include "lxc_error.h"*/
+
+/* from lxccontainer.h */
+struct lxc_container {
+  char *name;
+  char *error_string;
+  int error_num;
+  //<other fun stuff>
+};
+
+#define LXC_FORK_ERR "01"
+
+#define DEBUG 1
+
+/* concatenate error numbers for later dumping */
+char *lxc_error_concat(char *error_string, char *lxc_error_code) {
+  char *new_error_string = NULL;
+
+  /* error code is always same length, +1 for last null */
+  size_t ERROR_LEN = 2 + 1;
+
+  if (!error_string) {
+    new_error_string = malloc(sizeof(lxc_error_code));
+    asprintf(&new_error_string, "%s", lxc_error_code);
+  } else {
+    /* error_string_len not null, can dereference and get length*/
+    size_t error_string_len = strlen(error_string) + 1;
+    if (DEBUG)
+      printf("error_string_len: %lu\n", error_string_len);
+    new_error_string = malloc(sizeof(error_string_len + ERROR_LEN ));
+    asprintf(&new_error_string, "%s:%s", error_string, lxc_error_code);
+  }
+  if (DEBUG)
+    printf("new_error_string: %s\n", new_error_string);
+
+  return new_error_string;
+}
+
+
+/* Make error printing human readable */
+/* massive case statement for up to 100 unique errors (2 digits per error) */
+/*void lxc_error_dump(struct lxc_container *c) {
+  
+  switch(lxc_error) {
+
+    case LXC_OOM_ERR :
+
+  }
+}*/
+
+/* main method for testing error handling functions */
+int main(void) {
+  /* argument parsing, fills up my_args in other functions */
+  //struct lxc_container *c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
+  struct lxc_container *c = NULL;
+  c = malloc(sizeof(struct lxc_container));
+  c->name = "test";
+  c->error_string = NULL;
+  c->error_num = -1;
+  if (DEBUG)
+    printf("LXC_FORK_ERR: %s\n", LXC_FORK_ERR);
+
+  /* container does things, sometime hits error */
+  //pid_t p = fork();
+  pid_t p = -1;
+  if (p < 0) {
+    if (DEBUG)
+      fprintf(stderr, "failed to fork task\n");
+
+    // lxc_error_dump(c);
+    c->error_string = lxc_error_concat("01:00:00:11:21", LXC_FORK_ERR);
+     
+    free(c);
+    exit(EXIT_FAILURE);
+  }
+  free(c);
+  exit(EXIT_SUCCESS);
+}

From 80d1c89d700c4af1e11599076f3aab812536e317 Mon Sep 17 00:00:00 2001
From: Yasmine Zakout <yazakout at cs.utexas.edu>
Date: Fri, 1 Dec 2017 11:10:55 -0600
Subject: [PATCH 3/6] Updated macro file to have readable string in comments

---
 src/lxc/tools/error.txt   |  84 ---------------------------
 src/lxc/tools/lxc_error.h | 143 ++++++++++++++++++++++++++++++++++++----------
 2 files changed, 114 insertions(+), 113 deletions(-)
 delete mode 100644 src/lxc/tools/error.txt

diff --git a/src/lxc/tools/error.txt b/src/lxc/tools/error.txt
deleted file mode 100644
index 92e3fdba9..000000000
--- a/src/lxc/tools/error.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-lxc_copy.c:518:		ERROR("Error: Renaming container %s to %s failed\n", c->name, newname);
-lxc_copy.c:866:		SYSERROR("Failed to set close-on-exec on file descriptor.");
-lxc_create.c:127:	ERROR("Error executing %s -h", path);
-lxc_create.c:329:		ERROR("Error creating container %s", c->name);
-lxc_destroy.c:236:			SYSERROR("failed to allocate memory");
-lxc_destroy.c:243:			ERROR("could not read %s", path);
-lxc_device.c:68:		SYSERROR("failed to fork task.");
-lxc_device.c:76:			ERROR("failed to enter netns of container.");
-lxc_device.c:82:			ERROR("failed to get interfaces list");
-lxc_device.c:109:		ERROR("%s must be run as root", argv[0]);
-lxc_device.c:135:		ERROR("%s doesn't exist", my_args.name);
-lxc_device.c:142:			ERROR("Failed to load rcfile");
-lxc_device.c:147:			ERROR("Out of memory setting new config filename");
-lxc_device.c:153:		ERROR("Container %s is not running.", c->name);
-lxc_device.c:158:		ERROR("Error: no command given (Please see --help output)");
-lxc_device.c:176:			ERROR("Failed to add %s to %s.", dev_name, c->name);
-lxc_device.c:187:			ERROR("Failed to del %s from %s.", dev_name, c->name);
-lxc_device.c:192:		ERROR("Error: Please use add or del (Please see --help output)");
-lxc_execute.c:149:		ERROR("Failed to create lxc_container");
-lxc_execute.c:156:			ERROR("Failed to load rcfile");
-lxc_execute.c:162:			ERROR("Out of memory setting new config filename");
-lxc_execute.c:170:			ERROR("missing command to execute!");
-lxc_execute.c:193:		ERROR("Failed run an application inside container");
-lxc_freeze.c:84:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
-lxc_freeze.c:91:			ERROR("Failed to load rcfile");
-lxc_freeze.c:97:			ERROR("Out of memory setting new config filename");
-lxc_freeze.c:104:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
-lxc_freeze.c:110:		ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name);
-lxc_init.c:102:		ERROR("Please specify a command to execute");
-lxc_init.c:171:			SYSERROR("Failed to change signal action");
-lxc_init.c:196:			SYSERROR("Failed to set signal mask");
-lxc_init.c:210:		ERROR("%s - Failed to exec \"%s\"", strerror(errno), my_args.argv[0]);
-lxc_init.c:224:		SYSERROR("Failed to set signal mask");
-lxc_init.c:274:			ERROR("%s - Failed to wait on child %d",
-lxc_monitor.c:126:				ERROR("Unable to open monitor on path: %s", my_args.lxcpath[i]);
-lxc_monitor.c:131:				SYSERROR("Unable to close monitor on path: %s", my_args.lxcpath[i]);
-lxc_monitor.c:144:		ERROR("failed to allocate memory");
-lxc_monitor.c:149:		ERROR("Name too long");
-lxc_monitor.c:154:		ERROR("failed to compile the regex '%s'", my_args.name);
-lxc_monitor.c:160:		SYSERROR("out of memory");
-lxc_snapshot.c:211:		ERROR("Error creating a snapshot");
-lxc_snapshot.c:230:		ERROR("Error destroying snapshot %s", snapname);
-lxc_snapshot.c:244:		ERROR("Error listing snapshots");
-lxc_snapshot.c:284:		ERROR("Error restoring snapshot %s", args->snapname);
-lxc_start.c:71:				SYSERROR("failed to create '%s'", path);
-lxc_start.c:80:			SYSERROR("failed to get the real path of '%s'", path);
-lxc_start.c:215:			ERROR("Failed to create lxc_container");
-lxc_start.c:220:			ERROR("Failed to load rcfile");
-lxc_start.c:226:			ERROR("Out of memory setting new config filename");
-lxc_start.c:234:			SYSERROR("failed to allocate memory");
-lxc_start.c:246:			ERROR("Failed to create lxc_container");
-lxc_start.c:263:		ERROR("Container is already running.");
-lxc_start.c:279:		ERROR("Executing '/sbin/init' with no configuration file may crash the host");
-lxc_start.c:285:			ERROR("failed to ensure pidfile '%s'", my_args.pidfile);
-lxc_start.c:325:		ERROR("The container failed to start.");
-lxc_start.c:327:			ERROR("To get more details, run the container in foreground mode.");
-lxc_start.c:328:		ERROR("Additional information can be obtained by setting the "
-lxc_top.c:152:		ERROR("stdin is not a tty");
-lxc_top.c:157:		SYSERROR("failed to get current terminal settings");
-lxc_top.c:171:		ERROR("failed to set new terminal settings");
-lxc_top.c:236:		ERROR("unable to read cgroup item %s", item);
-lxc_top.c:255:		ERROR("unable to read cgroup item %s", item);
-lxc_top.c:311:		ERROR("unable to read cgroup item %s", item);
-lxc_top.c:540:			ERROR("cannot alloc mem");
-lxc_top.c:546:				ERROR("cannot alloc mem");
-lxc_top.c:566:		ERROR("failed to setup terminal");
-lxc_top.c:576:		ERROR("failed to create mainloop");
-lxc_top.c:582:		ERROR("failed to add stdin handler");
-lxc_unfreeze.c:83:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
-lxc_unfreeze.c:88:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
-lxc_unfreeze.c:96:			ERROR("Failed to load rcfile");
-lxc_unfreeze.c:102:			ERROR("Out of memory setting new config filename");
-lxc_unfreeze.c:109:		ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name);
-lxc_unshare.c:84:			ERROR("invalid username %s", name);
-lxc_unshare.c:91:			ERROR("invalid uid %u", *uid);
-lxc_unshare.c:122:			ERROR("failed to set hostname %s: %s", want_hostname, strerror(errno));
-lxc_unshare.c:128:		ERROR("failed to set uid %d: %s", uid, strerror(errno));
-lxc_unshare.c:134:	ERROR("failed to exec: '%s': %s", args[0], strerror(errno));
-lxc_unshare.c:192:		ERROR("a command to execute in the new namespace is required");
-lxc_unshare.c:232:		ERROR("-i <interfacename> needs -s NETWORK option");
-lxc_unshare.c:237:		ERROR("-H <hostname> needs -s UTSNAME option");
-lxc_unshare.c:242:		ERROR("-M needs -s MOUNT option");
-lxc_unshare.c:248:		ERROR("failed to clone");
-lxc_unshare.c:263:		ERROR("failed to wait for '%d'", pid);
diff --git a/src/lxc/tools/lxc_error.h b/src/lxc/tools/lxc_error.h
index c58f0ecd8..0308173c8 100644
--- a/src/lxc/tools/lxc_error.h
+++ b/src/lxc/tools/lxc_error.h
@@ -1,61 +1,146 @@
 // These should be organized in a way that makes more sense
 
-// lxc_copy.c: 518; lxc_unshare.c: 248
+// lxc_copy.c:518:		ERROR("Error: Renaming container %s to %s failed\n", c->name, newname);
+// lxc_unshare.c:248:		ERROR("failed to clone");
 #define LXC_CLONE_ERR 1 
-//lxc_copy.c: 866
+
+// lxc_copy.c:866:		SYSERROR("Failed to set close-on-exec on file descriptor.");
 #define LXC_FD_ERR 2
-//lxc_create.c:127, lxc_init.c: 210; lxc_unshare.c: 134
+
+// TODO lxc_create.c:127:	ERROR("Error executing %s -h", path);
+// lxc_init.c:210:		ERROR("%s - Failed to exec \"%s\"", strerror(errno), my_args.argv[0]);
+// lxc_unshare.c:134:	ERROR("failed to exec: '%s': %s", args[0], strerror(errno));
 #define LXC_EXEC_ERR 3
-//lxc_create.c:329; lxc_execute.c: 149; lxc_start.c: 215; 246
+
+// lxc_create.c:329:		ERROR("Error creating container %s", c->name);
+// lxc_execute.c:149:		ERROR("Failed to create lxc_container");
+// lxc_start.c:215:			ERROR("Failed to create lxc_container");
+// lxc_start.c:246:			ERROR("Failed to create lxc_container");
 #define LXC_CREATE_ERR 4
-//lxc_destroy.c: 236; lxc_monitor.c: 144; lxc_start.c:234; lxc_top.c: 540, 546
+
 // maybe combined with OOM, idk what else can go wrong with calloc
+// lxc_destroy.c:236:			SYSERROR("failed to allocate memory");
+// lxc_monitor.c:144:		ERROR("failed to allocate memory");
+// lxc_top.c:540:			ERROR("cannot alloc mem");
+// lxc_top.c:546:				ERROR("cannot alloc mem");
+// lxc_start.c:234:			SYSERROR("failed to allocate memory");
 #define LXC_MEM_ALLOC_ERR 5
-//lxc_destroy.c: 243
+
+// lxc_destroy.c:243:			ERROR("could not read %s", path);
 #define LXC_FILE_READ_ERR 6
-//lxc_device.c: 68
+
+// lxc_device.c:68:		SYSERROR("failed to fork task.");
 #define LXC_FORK_ERR 7
-//lxc_device.c: 76
+
+// lxc_device.c:76:			ERROR("failed to enter netns of container.");
 #define LXC_NS_ERR 8
-//lxc_device.c: 82
+
+// lxc_device.c:82:			ERROR("failed to get interfaces list");
 #define LXC_NETIF_ERR 9
-//lxc_device.c: 109; lxc_freeze.c: 104; lxc_unfreeze.c: 83
+
+// lxc_device.c:109:		ERROR("%s must be run as root", argv[0]);
+// lxc_freeze.c:104:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
+// lxc_unfreeze.c:88:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
 #define LXC_INSUF_PRIV_ERR 10
-//lxc_device.c: 135; lxc_freeze.c: 84; lxc_unfreeze.c: 83
+
+// lxc_device.c:135:		ERROR("%s doesn't exist", my_args.name);
+// lxc_freeze.c:84:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
+// lxc_unfreeze.c:83:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
 #define LXC_CONT_EXIST_ERR 11
-//lxc_device.c: 142; lxc_execute.c:156; lxc_freeze.c: 91; lxc_start.c: 220; lxc_unfreeze.c: 96
+
+// lxc_device.c:142:			ERROR("Failed to load rcfile");
+// lxc_execute.c:156:			ERROR("Failed to load rcfile");
+// lxc_freeze.c:91:			ERROR("Failed to load rcfile");
+// lxc_start.c:220:			ERROR("Failed to load rcfile");
+// lxc_unfreeze.c:96:			ERROR("Failed to load rcfile");
 #define LXC_RCFILE_ERR 12
-//lxc_device.c: 147; lxc_execute.c: 162; lxc_freeze.c: 97; lxc_monitor.c: 160; lxc_start.c: 246; lxc_unfreeze.c: 102
+
+// lxc_device.c:147:			ERROR("Out of memory setting new config filename");
+// lxc_execute.c:162:			ERROR("Out of memory setting new config filename");
+// lxc_freeze.c:97:			ERROR("Out of memory setting new config filename");
+// lxc_monitor.c:160:		SYSERROR("out of memory");
+// lxc_start.c:226:			ERROR("Out of memory setting new config filename");
+// lxc_unfreeze.c:102:			ERROR("Out of memory setting new config filename");
 #define LXC_OOM_ERR 13
-//lxc_device.c: 176, 187
+
+// lxc_device.c:176:			ERROR("Failed to add %s to %s.", dev_name, c->name);
+// lxc_device.c:187:			ERROR("Failed to del %s from %s.", dev_name, c->name);
 #define LXC_DEVICE_ERR 14
-//lxc_device.c: 192; lxc_execute.c: 170; lxc_init.c: 102; lxc_monitor.c: 149, 154; lxc_start.c: 263, 279 285; lxc_unshare.c: 84, 91, 192, 232, 237, 242
+
+// lxc_device.c:153:		ERROR("Container %s is not running.", c->name);
+// lxc_device.c:158:		ERROR("Error: no command given (Please see --help output)");
+// lxc_device.c:192:		ERROR("Error: Please use add or del (Please see --help output)");
+// lxc_execute.c:170:			ERROR("missing command to execute!");
+// lxc_init.c:102:		ERROR("Please specify a command to execute");
+// lxc_monitor.c:149:		ERROR("Name too long");
+// lxc_monitor.c:154:		ERROR("failed to compile the regex '%s'", my_args.name);
+// lxc_start.c:279:		ERROR("Executing '/sbin/init' with no configuration file may crash the host");
+// lxc_start.c:285:			ERROR("failed to ensure pidfile '%s'", my_args.pidfile);
+// lxc_start.c:263:		ERROR("Container is already running.");
+// lxc_unshare.c:84:			ERROR("invalid username %s", name);
+// lxc_unshare.c:91:			ERROR("invalid uid %u", *uid);
+// lxc_unshare.c:192:		ERROR("a command to execute in the new namespace is required");
+// lxc_unshare.c:232:		ERROR("-i <interfacename> needs -s NETWORK option");
+// lxc_unshare.c:237:		ERROR("-H <hostname> needs -s UTSNAME option");
+// lxc_unshare.c:242:		ERROR("-M needs -s MOUNT option");
 #define LXC_ARGS_INVAL 15
-//lxc_execute.c: 193
+
+// lxc_execute.c:193:		ERROR("Failed run an application inside container");
 #define LXC_APP_ERR 16
-//lxc_freeze.c: 110
+
+// lxc_freeze.c:110:		ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name);
 #define LXC_FREEZE_ERR 17
-//lxc_init.c: 171
+
+// lxc_init.c:171:			SYSERROR("Failed to change signal action");
 #define LXC_SIGACTION_ERR 18
-//lxc_init.c: 196, 224
+
+// lxc_init.c:196:			SYSERROR("Failed to set signal mask");
+// lxc_init.c:224:		SYSERROR("Failed to set signal mask");
 #define LXC_SIGMSK_ERR 19
-// lxc_init.c: 274; lxc_unshare.c: 263
+
+// lxc_init.c:274:			ERROR("%s - Failed to wait on child %d",
+// lxc_unshare.c:263:		ERROR("failed to wait for '%d'", pid);
 #define LXC_WAIT_ERR 20
-//lxc_monitor.c: 126, 131
+
+// lxc_monitor.c:126:				ERROR("Unable to open monitor on path: %s", my_args.lxcpath[i]);
+// lxc_monitor.c:131:				SYSERROR("Unable to close monitor on path: %s", my_args.lxcpath[i]);
 #define LXC_MONITOR_ERR 21
-//lxc_snapshot.c:211, 230, 244, 284
+
+// lxc_snapshot.c:211:		ERROR("Error creating a snapshot");
+// lxc_snapshot.c:230:		ERROR("Error destroying snapshot %s", snapname);
+// lxc_snapshot.c:244:		ERROR("Error listing snapshots");
+// lxc_snapshot.c:284:		ERROR("Error restoring snapshot %s", args->snapname);
 #define LXC_SNAPSHOT_ERR 22
-//lxc_start.c: 71, 80
+
+// lxc_start.c:71:				SYSERROR("failed to create '%s'", path);
+// lxc_start.c:80:			SYSERROR("failed to get the real path of '%s'", path);
 #define LXC_PATH_ERR 23
-//lxc_start.c: 325
+
+// lxc_start.c:325:		ERROR("The container failed to start.");
 #define LXC_START_ERR 24
-//lxc_top.c: 152; 157, 566, 576, 582
+
+// lxc_top.c:152:		ERROR("stdin is not a tty");
+// lxc_top.c:171:		ERROR("failed to set new terminal settings");
+// lxc_top.c:566:		ERROR("failed to setup terminal");
+// lxc_top.c:576:		ERROR("failed to create mainloop");
+// lxc_top.c:582:		ERROR("failed to add stdin handler");
+// lxc_top.c:157:		SYSERROR("failed to get current terminal settings");
 #define LXC_TOP_ERR 25
-//lxc_top.c: 236, 255, 311
+
+// lxc_top.c:236:		ERROR("unable to read cgroup item %s", item);
+// lxc_top.c:255:		ERROR("unable to read cgroup item %s", item);
+// lxc_top.c:311:		ERROR("unable to read cgroup item %s", item);
 #define LXC_READ_CGROUP_ERR 26
-//lxc_unfreeze.c: 109
+
+// lxc_unfreeze.c:109:		ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name);
 #define LXC_UNFREEZE_ERR 27
-//lxc_unshared.c: 128
+
+// lxc_unshare.c:128:		ERROR("failed to set uid %d: %s", uid, strerror(errno));
 #define LXC_UID_ERR 28
-//lxc_unshare.c:122
+
+// lxc_unshare.c:122:			ERROR("failed to set hostname %s: %s", want_hostname, strerror(errno));
 #define LXC_HOSTNAME_ERR 29
+
+// MISC: used as printf
+// lxc_start.c:327:			ERROR("To get more details, run the container in foreground mode.");
+// lxc_start.c:328:		ERROR("Additional information can be obtained by setting the "

From b56fdc92a29843e4d8ab3bbd5ac9d60679dfbd93 Mon Sep 17 00:00:00 2001
From: AustinReichert <austinskyreichert at utexas.edu>
Date: Mon, 4 Dec 2017 16:05:06 -0600
Subject: [PATCH 4/6] skeleton for error handling, requires review

Signed-off-by: AustinReichert <austinskyreichert at utexas.edu>
---
 src/lxc/lxc_error.c | 232 +++++++++++++++++++++++++++++++++++++++++-----------
 src/lxc/lxc_error.h | 162 ++++++++++++++++++++++++++++++++++++
 2 files changed, 347 insertions(+), 47 deletions(-)
 create mode 100644 src/lxc/lxc_error.h

diff --git a/src/lxc/lxc_error.c b/src/lxc/lxc_error.c
index 4756f7139..cbe78472f 100644
--- a/src/lxc/lxc_error.c
+++ b/src/lxc/lxc_error.c
@@ -1,5 +1,5 @@
 #ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
+#define _GNU_SOURCE
 #endif
 
 //#include "config.h"
@@ -28,82 +28,220 @@
 #include "list.h"
 #include "mainloop.h"
 #include "utils.h"
-
-#include "lxc_error.h"*/
+*/
+#include "lxc_error.h"
 
 /* from lxccontainer.h */
-struct lxc_container {
+/* struct lxc_container {
   char *name;
   char *error_string;
   int error_num;
   //<other fun stuff>
-};
-
-#define LXC_FORK_ERR "01"
-
-#define DEBUG 1
-
-/* concatenate error numbers for later dumping */
-char *lxc_error_concat(char *error_string, char *lxc_error_code) {
-  char *new_error_string = NULL;
-
-  /* error code is always same length, +1 for last null */
-  size_t ERROR_LEN = 2 + 1;
-
-  if (!error_string) {
-    new_error_string = malloc(sizeof(lxc_error_code));
-    asprintf(&new_error_string, "%s", lxc_error_code);
+}; */
+
+#define DEBUG 0
+#define LXC_MALLOC_ERR "Malloc failed"
+
+/* need to work on memory leaks */
+
+/* concatenate error numbers for later dumping, could just as easily use a queue
+ * to store them, but struct element is char * and I haven't asked them about it */
+void *lxc_error_concat(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE)
+{
+  char *error_string = c->error_string;
+  int error_num = c->error_num;
+  size_t error_string_len = 0;
+  size_t error_len = 0;
+  char *new_error_string;
+  int new_error_num;
+
+  /* nothing changes */
+  if ((!error_string && !lxc_error) || (error_string && !lxc_error)) {
+    new_error_string = error_string;
+    new_error_num = error_num;
+  } else if (!error_string && lxc_error) {
+    /* lxc_error not null, can dereference and get length + 1 for NULL */
+    error_len = strlen(lxc_error) + 1;
+    new_error_string = malloc(error_len);
+
+    if (!new_error_string) {
+      fprintf(stderr, "%s\n", LXC_MALLOC_ERR);
+      exit(EXIT_FAILURE);
+    }
+
+    asprintf(&new_error_string, "%s", lxc_error);
+    new_error_num = LXC_ERROR_CODE;
   } else {
-    /* error_string_len not null, can dereference and get length*/
-    size_t error_string_len = strlen(error_string) + 1;
-    if (DEBUG)
-      printf("error_string_len: %lu\n", error_string_len);
-    new_error_string = malloc(sizeof(error_string_len + ERROR_LEN ));
-    asprintf(&new_error_string, "%s:%s", error_string, lxc_error_code);
+    /* error_string not null, can dereference and get length + 1 for NULL */
+    error_string_len = strlen(error_string) + 1;
+    error_len = strlen(lxc_error) + 1;
+
+    /* extra byte for duplicate delimiter could avoid confusion */
+    int new_error_len = error_string_len + error_len;
+    new_error_string = malloc(new_error_len);
+
+    if (!new_error_string) {
+      fprintf(stderr, "%s\n", LXC_MALLOC_ERR);
+      exit(EXIT_FAILURE);
+    }
+
+    asprintf(&new_error_string, "%s~%s", error_string, lxc_error);
+    new_error_num = LXC_ERROR_CODE;
+    free(error_string);
   }
-  if (DEBUG)
-    printf("new_error_string: %s\n", new_error_string);
+  c->error_string = new_error_string;
+  c->error_num = new_error_num;
+}
 
-  return new_error_string;
+/* Make error printing human readable, and reset error_string to new error */
+void lxc_error_dump(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE)
+{
+  /* intelligence for error dump */
+  int dump;
+  switch (LXC_ERROR_CODE) {
+    case LXC_FORK_ERR :
+      dump = 1;
+      break;
+    case LXC_FD_ERR :
+      dump = 0;
+      break;
+    /* etc...
+     *
+     *
+     */
+    default :
+      dump = 0;
+  } 
+
+  /* dump and concat, dump just changes initial condition */
+  if (dump) {
+    char *local_str = malloc(strlen(c->error_string) + 1);
+    if (!local_str) {
+      fprintf(stderr, "%s\n", LXC_MALLOC_ERR);
+      exit(EXIT_FAILURE);
+    }
+    strcpy(local_str, c->error_string);
+
+    char *head = local_str;
+    char *strerror = strtok_r(head, "~", &head);
+
+    printf("lxc_error_dump:\n");
+    while (strerror != NULL) {
+      printf("\t%s\n", strerror);
+      strerror = strtok_r(head, "~", &head);
+    }
+
+    free(local_str);
+    free(c->error_string);
+    c->error_string = NULL;
+    c->error_num = -1;
+  }
+  lxc_error_concat(c, lxc_error, LXC_ERROR_CODE);
 }
 
+/* to be filled in later by various error handling codes */
+int lxc_error_handle(struct lxc_container *c)
+{
+  int error_num = c->error_num;
+  int success = 0;
+
+  switch (error_num) {
+    case LXC_FORK_ERR :
+      //success = handle_fork_err(); 
+      break;
+    case LXC_FD_ERR :
+      //success = handle_fd_err(); 
+      break;
+    /* etc...
+     *
+     *
+     */
+    default :
+      printf("Unknown error code\n");
+  } 
+  return success;
+}
 
-/* Make error printing human readable */
-/* massive case statement for up to 100 unique errors (2 digits per error) */
-/*void lxc_error_dump(struct lxc_container *c) {
+//lxc_error_dump(c, lxc_error, LXC_FORK_ERR);
+void test_dump(struct lxc_container *c)
+{
+  /* test zero, start null */
+  printf("Before test zero, expect '(null)' and '-1'\n \
+      c->error_string: %s, c->error_num: %d\n", c->error_string, c->error_num);
+
+  lxc_error_dump(c, "this should concatenate", 20);
+  printf("After test zero, expect 'this should concatenate' and '20'\n \
+      c->error_string: %s, c->error_num: %d\n", c->error_string, c->error_num);
+
+  /* test one */
+  lxc_error_dump(c, "one more err", 21);
+  printf("After test one, expect 'this should concatenate~one more err' and '21'\n \
+      c->error_string: %s, c->error_num: %d\n", c->error_string, c->error_num);
+
+  /* test two */
+  lxc_error_dump(c, NULL, 30);
+  printf("After test two, expect 'this should concatenate~one more err' and '21'\n \
+      c->error_string: %s, c->error_num: %d\n", c->error_string, c->error_num);
+
+  /* test three */
+  lxc_error_dump(c, "failed to fork", LXC_FORK_ERR);
+  printf("After test three, expect dump of errors and now 'failed to fork' and '7'\n \
+      c->error_string: %s, c->error_num: %d\n", c->error_string, c->error_num);
   
-  switch(lxc_error) {
-
-    case LXC_OOM_ERR :
-
-  }
-}*/
+  free(c->error_string);
+}
 
 /* main method for testing error handling functions */
-int main(void) {
-  /* argument parsing, fills up my_args in other functions */
+/* argument parsing, fills up my_args in other functions */
+int main(void)
+{
   //struct lxc_container *c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
   struct lxc_container *c = NULL;
+  char *lxc_error = NULL;
   c = malloc(sizeof(struct lxc_container));
+
+  if (!c) {
+    printf("%s\n", LXC_MALLOC_ERR);
+    exit(EXIT_FAILURE);
+  }
+
   c->name = "test";
   c->error_string = NULL;
   c->error_num = -1;
-  if (DEBUG)
-    printf("LXC_FORK_ERR: %s\n", LXC_FORK_ERR);
 
   /* container does things, sometime hits error */
   //pid_t p = fork();
   pid_t p = -1;
   if (p < 0) {
-    if (DEBUG)
-      fprintf(stderr, "failed to fork task\n");
+    /* how it looks now */
+    //fprintf(stderr, "failed to fork task\n"); OR SYSERROR("failed to fork task");
+
+    /* these next 3 lines are the goal, to get added everywhere */
+    //lxc_error = "failed to fork task";
+    //SYSERROR(%s, lxc_error);
+    //lxc_error_dump(c, lxc_error, LXC_FORK_ERR);
+
+    test_dump(c);
 
-    // lxc_error_dump(c);
-    c->error_string = lxc_error_concat("01:00:00:11:21", LXC_FORK_ERR);
-     
     free(c);
     exit(EXIT_FAILURE);
   }
   free(c);
   exit(EXIT_SUCCESS);
 }
+
+/* Notes
+ *
+ * 1. Thought we might be able to store a couple of string digits that would
+ *    map to an error, which would then get translated into the full string
+ *    error codes they represent upon "dumping" the errors.
+ *    Issue: Mix of generic and specific print statements, %s, %d, OOM, etc
+ *    Resolution: Only use codes for error_num, lxc_error passed instead
+ *
+ * 2. Tried to mirror format of existing *.h files with #ifdef/etc
+ * 
+ * 3. Could come up with a better ordering for macros (by file?)
+ *
+ * 4. Way to pinpoint file + error together (my_args.progname)
+ *
+ */
diff --git a/src/lxc/lxc_error.h b/src/lxc/lxc_error.h
new file mode 100644
index 000000000..e3ce6e660
--- /dev/null
+++ b/src/lxc/lxc_error.h
@@ -0,0 +1,162 @@
+#ifndef __LXC_ERRORS_H
+#define __LXC_ERRORS_H
+
+// These should be organized in a way that makes more sense
+
+// lxc_copy.c:518:		ERROR("Error: Renaming container %s to %s failed\n", c->name, newname);
+// lxc_unshare.c:248:		ERROR("failed to clone");
+#define LXC_CLONE_ERR 1 
+
+// lxc_copy.c:866:		SYSERROR("Failed to set close-on-exec on file descriptor.");
+#define LXC_FD_ERR 2
+
+// TODO lxc_create.c:127:	ERROR("Error executing %s -h", path);
+// lxc_init.c:210:		ERROR("%s - Failed to exec \"%s\"", strerror(errno), my_args.argv[0]);
+// lxc_unshare.c:134:	ERROR("failed to exec: '%s': %s", args[0], strerror(errno));
+#define LXC_EXEC_ERR 3
+
+// lxc_create.c:329:		ERROR("Error creating container %s", c->name);
+// lxc_execute.c:149:		ERROR("Failed to create lxc_container");
+// lxc_start.c:215:			ERROR("Failed to create lxc_container");
+// lxc_start.c:246:			ERROR("Failed to create lxc_container");
+#define LXC_CREATE_ERR 4
+
+// maybe combined with OOM, idk what else can go wrong with calloc
+// lxc_destroy.c:236:			SYSERROR("failed to allocate memory");
+// lxc_monitor.c:144:		ERROR("failed to allocate memory");
+// lxc_top.c:540:			ERROR("cannot alloc mem");
+// lxc_top.c:546:				ERROR("cannot alloc mem");
+// lxc_start.c:234:			SYSERROR("failed to allocate memory");
+#define LXC_MEM_ALLOC_ERR 5
+
+// lxc_destroy.c:243:			ERROR("could not read %s", path);
+#define LXC_FILE_READ_ERR 6
+
+// lxc_device.c:68:		SYSERROR("failed to fork task.");
+#define LXC_FORK_ERR 7
+
+// lxc_device.c:76:			ERROR("failed to enter netns of container.");
+#define LXC_NS_ERR 8
+
+// lxc_device.c:82:			ERROR("failed to get interfaces list");
+#define LXC_NETIF_ERR 9
+
+// lxc_device.c:109:		ERROR("%s must be run as root", argv[0]);
+// lxc_freeze.c:104:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
+// lxc_unfreeze.c:88:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
+#define LXC_INSUF_PRIV_ERR 10
+
+// lxc_device.c:135:		ERROR("%s doesn't exist", my_args.name);
+// lxc_freeze.c:84:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
+// lxc_unfreeze.c:83:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
+#define LXC_CONT_EXIST_ERR 11
+
+// lxc_device.c:142:			ERROR("Failed to load rcfile");
+// lxc_execute.c:156:			ERROR("Failed to load rcfile");
+// lxc_freeze.c:91:			ERROR("Failed to load rcfile");
+// lxc_start.c:220:			ERROR("Failed to load rcfile");
+// lxc_unfreeze.c:96:			ERROR("Failed to load rcfile");
+#define LXC_RCFILE_ERR 12
+
+// lxc_device.c:147:			ERROR("Out of memory setting new config filename");
+// lxc_execute.c:162:			ERROR("Out of memory setting new config filename");
+// lxc_freeze.c:97:			ERROR("Out of memory setting new config filename");
+// lxc_monitor.c:160:		SYSERROR("out of memory");
+// lxc_start.c:226:			ERROR("Out of memory setting new config filename");
+// lxc_unfreeze.c:102:			ERROR("Out of memory setting new config filename");
+#define LXC_OOM_ERR 13
+
+// lxc_device.c:176:			ERROR("Failed to add %s to %s.", dev_name, c->name);
+// lxc_device.c:187:			ERROR("Failed to del %s from %s.", dev_name, c->name);
+#define LXC_DEVICE_ERR 14
+
+// lxc_device.c:153:		ERROR("Container %s is not running.", c->name);
+// lxc_device.c:158:		ERROR("Error: no command given (Please see --help output)");
+// lxc_device.c:192:		ERROR("Error: Please use add or del (Please see --help output)");
+// lxc_execute.c:170:			ERROR("missing command to execute!");
+// lxc_init.c:102:		ERROR("Please specify a command to execute");
+// lxc_monitor.c:149:		ERROR("Name too long");
+// lxc_monitor.c:154:		ERROR("failed to compile the regex '%s'", my_args.name);
+// lxc_start.c:279:		ERROR("Executing '/sbin/init' with no configuration file may crash the host");
+// lxc_start.c:285:			ERROR("failed to ensure pidfile '%s'", my_args.pidfile);
+// lxc_start.c:263:		ERROR("Container is already running.");
+// lxc_unshare.c:84:			ERROR("invalid username %s", name);
+// lxc_unshare.c:91:			ERROR("invalid uid %u", *uid);
+// lxc_unshare.c:192:		ERROR("a command to execute in the new namespace is required");
+// lxc_unshare.c:232:		ERROR("-i <interfacename> needs -s NETWORK option");
+// lxc_unshare.c:237:		ERROR("-H <hostname> needs -s UTSNAME option");
+// lxc_unshare.c:242:		ERROR("-M needs -s MOUNT option");
+#define LXC_ARGS_INVAL 15
+
+// lxc_execute.c:193:		ERROR("Failed run an application inside container");
+#define LXC_APP_ERR 16
+
+// lxc_freeze.c:110:		ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name);
+#define LXC_FREEZE_ERR 17
+
+// lxc_init.c:171:			SYSERROR("Failed to change signal action");
+#define LXC_SIGACTION_ERR 18
+
+// lxc_init.c:196:			SYSERROR("Failed to set signal mask");
+// lxc_init.c:224:		SYSERROR("Failed to set signal mask");
+#define LXC_SIGMSK_ERR 19
+
+// lxc_init.c:274:			ERROR("%s - Failed to wait on child %d",
+// lxc_unshare.c:263:		ERROR("failed to wait for '%d'", pid);
+#define LXC_WAIT_ERR 20
+
+// lxc_monitor.c:126:				ERROR("Unable to open monitor on path: %s", my_args.lxcpath[i]);
+// lxc_monitor.c:131:				SYSERROR("Unable to close monitor on path: %s", my_args.lxcpath[i]);
+#define LXC_MONITOR_ERR 21
+
+// lxc_snapshot.c:211:		ERROR("Error creating a snapshot");
+// lxc_snapshot.c:230:		ERROR("Error destroying snapshot %s", snapname);
+// lxc_snapshot.c:244:		ERROR("Error listing snapshots");
+// lxc_snapshot.c:284:		ERROR("Error restoring snapshot %s", args->snapname);
+#define LXC_SNAPSHOT_ERR 22
+
+// lxc_start.c:71:				SYSERROR("failed to create '%s'", path);
+// lxc_start.c:80:			SYSERROR("failed to get the real path of '%s'", path);
+#define LXC_PATH_ERR 23
+
+// lxc_start.c:325:		ERROR("The container failed to start.");
+#define LXC_START_ERR 24
+
+// lxc_top.c:152:		ERROR("stdin is not a tty");
+// lxc_top.c:171:		ERROR("failed to set new terminal settings");
+// lxc_top.c:566:		ERROR("failed to setup terminal");
+// lxc_top.c:576:		ERROR("failed to create mainloop");
+// lxc_top.c:582:		ERROR("failed to add stdin handler");
+// lxc_top.c:157:		SYSERROR("failed to get current terminal settings");
+#define LXC_TOP_ERR 25
+
+// lxc_top.c:236:		ERROR("unable to read cgroup item %s", item);
+// lxc_top.c:255:		ERROR("unable to read cgroup item %s", item);
+// lxc_top.c:311:		ERROR("unable to read cgroup item %s", item);
+#define LXC_READ_CGROUP_ERR 26
+
+// lxc_unfreeze.c:109:		ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name);
+#define LXC_UNFREEZE_ERR 27
+
+// lxc_unshare.c:128:		ERROR("failed to set uid %d: %s", uid, strerror(errno));
+#define LXC_UID_ERR 28
+
+// lxc_unshare.c:122:			ERROR("failed to set hostname %s: %s", want_hostname, strerror(errno));
+#define LXC_HOSTNAME_ERR 29
+
+// MISC: used as printf
+// lxc_start.c:327:			ERROR("To get more details, run the container in foreground mode.");
+// lxc_start.c:328:		ERROR("Additional information can be obtained by setting the "
+
+struct lxc_container {
+  char *name;
+  char *error_string;
+  int error_num;
+  /* other fun stuff */
+}; 
+
+extern void *lxc_error_concat(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE);
+extern void lxc_error_dump(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE);
+extern int lxc_error_handle(struct lxc_container *c);
+
+#endif /* __LXC_ERRORS_H */

From c9ca078a467facc733d9278015ab47a15edd3b3f Mon Sep 17 00:00:00 2001
From: AustinReichert <austinskyreichert at utexas.edu>
Date: Mon, 4 Dec 2017 16:56:07 -0600
Subject: [PATCH 5/6] added documentation to lxc_error.h

Signed-off-by: AustinReichert <austinskyreichert at utexas.edu>
---
 src/lxc/lxc_error.c | 15 +--------------
 src/lxc/lxc_error.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/src/lxc/lxc_error.c b/src/lxc/lxc_error.c
index cbe78472f..511f221ef 100644
--- a/src/lxc/lxc_error.c
+++ b/src/lxc/lxc_error.c
@@ -42,10 +42,8 @@
 #define DEBUG 0
 #define LXC_MALLOC_ERR "Malloc failed"
 
-/* need to work on memory leaks */
-
 /* concatenate error numbers for later dumping, could just as easily use a queue
- * to store them, but struct element is char * and I haven't asked them about it */
+ * to store them, but struct element is char */
 void *lxc_error_concat(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE)
 {
   char *error_string = c->error_string;
@@ -216,11 +214,6 @@ int main(void)
     /* how it looks now */
     //fprintf(stderr, "failed to fork task\n"); OR SYSERROR("failed to fork task");
 
-    /* these next 3 lines are the goal, to get added everywhere */
-    //lxc_error = "failed to fork task";
-    //SYSERROR(%s, lxc_error);
-    //lxc_error_dump(c, lxc_error, LXC_FORK_ERR);
-
     test_dump(c);
 
     free(c);
@@ -239,9 +232,3 @@ int main(void)
  *    Resolution: Only use codes for error_num, lxc_error passed instead
  *
  * 2. Tried to mirror format of existing *.h files with #ifdef/etc
- * 
- * 3. Could come up with a better ordering for macros (by file?)
- *
- * 4. Way to pinpoint file + error together (my_args.progname)
- *
- */
diff --git a/src/lxc/lxc_error.h b/src/lxc/lxc_error.h
index e3ce6e660..f4d0b5a4c 100644
--- a/src/lxc/lxc_error.h
+++ b/src/lxc/lxc_error.h
@@ -1,6 +1,52 @@
 #ifndef __LXC_ERRORS_H
 #define __LXC_ERRORS_H
 
+/* Overview 
+ *
+ * 1. Error codes defined based on grepping for "error" in tools/
+ *
+ * 2. lxc_error_dump() has intelligence to know when/if to dump errors and concat,
+ *    or just concatenate, thus only needing to add one lxc_error_dump call per
+ *    error to capture, and all that needs to be known is what type of error it is.
+ *
+ * 3. lxc_error_concat() is called by lxc_error_dump and has logic for appropriately
+ *    concatenating past/new error strings. Used '~' as delimiter since it's the least
+ *    used ASCII character, reduces need for escaping. If not sufficient can use, "~~" :)
+ *
+ * 4. lxc_error_handle() can be called to look at the most recent error_num and run
+ *    some code to "handle" it in some way, then return success/failure
+ *
+ * 5. main() and test_dump() are only there for testing at this point, it will be removed
+ *
+ * Example:
+ *   if (something_did_not_work) {
+ *     char *lxc_error = "<some-error>";
+ *     SYSERROR("%s", lxc_error);
+ *     lxc_error_dump(c, lxc_error, <LXC_ERROR_CODE>);
+ *   }
+ *
+ * Issues:
+ * 1. Can only store errors where a struct lxc_container *c is accessible, this
+ *    means lots of liblxc files cannot use this. How to resolve this/is this a
+ *    problem? Shouldn't the container try to handle errors from functions it can't
+ *    see inside of?
+ *
+ * 2. Would like to be able to identify which file the error occurred in. i.e.
+ *    "lxc_attach: Out of memory", but not sure how to do it (aside from manually).
+ *    Trying to figure out a way to use my_args.progname, but any other suggestions
+ *    welcome.
+ *
+ * 3. Need a better ordering for macros, and way to determine which are considered
+ *    leaf vs non-leaf
+ *
+ * 4. Need to figure out how/which errors should/can be handled/ignored.
+ *
+ * 5. Incorporate into Makefile and build, handle dependencies and decide #includes
+ *
+ * 6. 3 memory leaks from lxc_error_concat
+ *
+ */
+
 // These should be organized in a way that makes more sense
 
 // lxc_copy.c:518:		ERROR("Error: Renaming container %s to %s failed\n", c->name, newname);
@@ -148,6 +194,7 @@
 // lxc_start.c:327:			ERROR("To get more details, run the container in foreground mode.");
 // lxc_start.c:328:		ERROR("Additional information can be obtained by setting the "
 
+/* temporary placeholder for testing */
 struct lxc_container {
   char *name;
   char *error_string;
@@ -158,5 +205,6 @@ struct lxc_container {
 extern void *lxc_error_concat(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE);
 extern void lxc_error_dump(struct lxc_container *c, char *lxc_error, int LXC_ERROR_CODE);
 extern int lxc_error_handle(struct lxc_container *c);
+extern void test_dump(struct lxc_container *c);
 
 #endif /* __LXC_ERRORS_H */

From a2420cba3b378aa4148c98c1b61c227d411835e8 Mon Sep 17 00:00:00 2001
From: AustinReichert <austinskyreichert at utexas.edu>
Date: Mon, 4 Dec 2017 16:58:57 -0600
Subject: [PATCH 6/6] removed duplicate file

Signed-off-by: AustinReichert <austinskyreichert at utexas.edu>
---
 src/lxc/tools/lxc_error.h | 146 ----------------------------------------------
 1 file changed, 146 deletions(-)
 delete mode 100644 src/lxc/tools/lxc_error.h

diff --git a/src/lxc/tools/lxc_error.h b/src/lxc/tools/lxc_error.h
deleted file mode 100644
index 0308173c8..000000000
--- a/src/lxc/tools/lxc_error.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// These should be organized in a way that makes more sense
-
-// lxc_copy.c:518:		ERROR("Error: Renaming container %s to %s failed\n", c->name, newname);
-// lxc_unshare.c:248:		ERROR("failed to clone");
-#define LXC_CLONE_ERR 1 
-
-// lxc_copy.c:866:		SYSERROR("Failed to set close-on-exec on file descriptor.");
-#define LXC_FD_ERR 2
-
-// TODO lxc_create.c:127:	ERROR("Error executing %s -h", path);
-// lxc_init.c:210:		ERROR("%s - Failed to exec \"%s\"", strerror(errno), my_args.argv[0]);
-// lxc_unshare.c:134:	ERROR("failed to exec: '%s': %s", args[0], strerror(errno));
-#define LXC_EXEC_ERR 3
-
-// lxc_create.c:329:		ERROR("Error creating container %s", c->name);
-// lxc_execute.c:149:		ERROR("Failed to create lxc_container");
-// lxc_start.c:215:			ERROR("Failed to create lxc_container");
-// lxc_start.c:246:			ERROR("Failed to create lxc_container");
-#define LXC_CREATE_ERR 4
-
-// maybe combined with OOM, idk what else can go wrong with calloc
-// lxc_destroy.c:236:			SYSERROR("failed to allocate memory");
-// lxc_monitor.c:144:		ERROR("failed to allocate memory");
-// lxc_top.c:540:			ERROR("cannot alloc mem");
-// lxc_top.c:546:				ERROR("cannot alloc mem");
-// lxc_start.c:234:			SYSERROR("failed to allocate memory");
-#define LXC_MEM_ALLOC_ERR 5
-
-// lxc_destroy.c:243:			ERROR("could not read %s", path);
-#define LXC_FILE_READ_ERR 6
-
-// lxc_device.c:68:		SYSERROR("failed to fork task.");
-#define LXC_FORK_ERR 7
-
-// lxc_device.c:76:			ERROR("failed to enter netns of container.");
-#define LXC_NS_ERR 8
-
-// lxc_device.c:82:			ERROR("failed to get interfaces list");
-#define LXC_NETIF_ERR 9
-
-// lxc_device.c:109:		ERROR("%s must be run as root", argv[0]);
-// lxc_freeze.c:104:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
-// lxc_unfreeze.c:88:		ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
-#define LXC_INSUF_PRIV_ERR 10
-
-// lxc_device.c:135:		ERROR("%s doesn't exist", my_args.name);
-// lxc_freeze.c:84:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
-// lxc_unfreeze.c:83:		ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name);
-#define LXC_CONT_EXIST_ERR 11
-
-// lxc_device.c:142:			ERROR("Failed to load rcfile");
-// lxc_execute.c:156:			ERROR("Failed to load rcfile");
-// lxc_freeze.c:91:			ERROR("Failed to load rcfile");
-// lxc_start.c:220:			ERROR("Failed to load rcfile");
-// lxc_unfreeze.c:96:			ERROR("Failed to load rcfile");
-#define LXC_RCFILE_ERR 12
-
-// lxc_device.c:147:			ERROR("Out of memory setting new config filename");
-// lxc_execute.c:162:			ERROR("Out of memory setting new config filename");
-// lxc_freeze.c:97:			ERROR("Out of memory setting new config filename");
-// lxc_monitor.c:160:		SYSERROR("out of memory");
-// lxc_start.c:226:			ERROR("Out of memory setting new config filename");
-// lxc_unfreeze.c:102:			ERROR("Out of memory setting new config filename");
-#define LXC_OOM_ERR 13
-
-// lxc_device.c:176:			ERROR("Failed to add %s to %s.", dev_name, c->name);
-// lxc_device.c:187:			ERROR("Failed to del %s from %s.", dev_name, c->name);
-#define LXC_DEVICE_ERR 14
-
-// lxc_device.c:153:		ERROR("Container %s is not running.", c->name);
-// lxc_device.c:158:		ERROR("Error: no command given (Please see --help output)");
-// lxc_device.c:192:		ERROR("Error: Please use add or del (Please see --help output)");
-// lxc_execute.c:170:			ERROR("missing command to execute!");
-// lxc_init.c:102:		ERROR("Please specify a command to execute");
-// lxc_monitor.c:149:		ERROR("Name too long");
-// lxc_monitor.c:154:		ERROR("failed to compile the regex '%s'", my_args.name);
-// lxc_start.c:279:		ERROR("Executing '/sbin/init' with no configuration file may crash the host");
-// lxc_start.c:285:			ERROR("failed to ensure pidfile '%s'", my_args.pidfile);
-// lxc_start.c:263:		ERROR("Container is already running.");
-// lxc_unshare.c:84:			ERROR("invalid username %s", name);
-// lxc_unshare.c:91:			ERROR("invalid uid %u", *uid);
-// lxc_unshare.c:192:		ERROR("a command to execute in the new namespace is required");
-// lxc_unshare.c:232:		ERROR("-i <interfacename> needs -s NETWORK option");
-// lxc_unshare.c:237:		ERROR("-H <hostname> needs -s UTSNAME option");
-// lxc_unshare.c:242:		ERROR("-M needs -s MOUNT option");
-#define LXC_ARGS_INVAL 15
-
-// lxc_execute.c:193:		ERROR("Failed run an application inside container");
-#define LXC_APP_ERR 16
-
-// lxc_freeze.c:110:		ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name);
-#define LXC_FREEZE_ERR 17
-
-// lxc_init.c:171:			SYSERROR("Failed to change signal action");
-#define LXC_SIGACTION_ERR 18
-
-// lxc_init.c:196:			SYSERROR("Failed to set signal mask");
-// lxc_init.c:224:		SYSERROR("Failed to set signal mask");
-#define LXC_SIGMSK_ERR 19
-
-// lxc_init.c:274:			ERROR("%s - Failed to wait on child %d",
-// lxc_unshare.c:263:		ERROR("failed to wait for '%d'", pid);
-#define LXC_WAIT_ERR 20
-
-// lxc_monitor.c:126:				ERROR("Unable to open monitor on path: %s", my_args.lxcpath[i]);
-// lxc_monitor.c:131:				SYSERROR("Unable to close monitor on path: %s", my_args.lxcpath[i]);
-#define LXC_MONITOR_ERR 21
-
-// lxc_snapshot.c:211:		ERROR("Error creating a snapshot");
-// lxc_snapshot.c:230:		ERROR("Error destroying snapshot %s", snapname);
-// lxc_snapshot.c:244:		ERROR("Error listing snapshots");
-// lxc_snapshot.c:284:		ERROR("Error restoring snapshot %s", args->snapname);
-#define LXC_SNAPSHOT_ERR 22
-
-// lxc_start.c:71:				SYSERROR("failed to create '%s'", path);
-// lxc_start.c:80:			SYSERROR("failed to get the real path of '%s'", path);
-#define LXC_PATH_ERR 23
-
-// lxc_start.c:325:		ERROR("The container failed to start.");
-#define LXC_START_ERR 24
-
-// lxc_top.c:152:		ERROR("stdin is not a tty");
-// lxc_top.c:171:		ERROR("failed to set new terminal settings");
-// lxc_top.c:566:		ERROR("failed to setup terminal");
-// lxc_top.c:576:		ERROR("failed to create mainloop");
-// lxc_top.c:582:		ERROR("failed to add stdin handler");
-// lxc_top.c:157:		SYSERROR("failed to get current terminal settings");
-#define LXC_TOP_ERR 25
-
-// lxc_top.c:236:		ERROR("unable to read cgroup item %s", item);
-// lxc_top.c:255:		ERROR("unable to read cgroup item %s", item);
-// lxc_top.c:311:		ERROR("unable to read cgroup item %s", item);
-#define LXC_READ_CGROUP_ERR 26
-
-// lxc_unfreeze.c:109:		ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name);
-#define LXC_UNFREEZE_ERR 27
-
-// lxc_unshare.c:128:		ERROR("failed to set uid %d: %s", uid, strerror(errno));
-#define LXC_UID_ERR 28
-
-// lxc_unshare.c:122:			ERROR("failed to set hostname %s: %s", want_hostname, strerror(errno));
-#define LXC_HOSTNAME_ERR 29
-
-// MISC: used as printf
-// lxc_start.c:327:			ERROR("To get more details, run the container in foreground mode.");
-// lxc_start.c:328:		ERROR("Additional information can be obtained by setting the "


More information about the lxc-devel mailing list