When integrating collie into cluster management scripts, it is useful to
be able to tell the difference between different types of error without
needing to parse human-readable error text. In addition to the standard
EXIT_SUCCESS (0) and EXIT_FAILURE (1) exit conditions, we introduce

  EXIT_SYSFAIL (2) - something is wrong with the cluster or local host
  EXIT_BUSY (3)    - an object is alredy in use, blocking the operation
  EXIT_FULL (4)    - no more space is left in the cluster
  EXIT_MISSING (5) - the specified object is not found
  EXIT_USAGE (64)  - standard EUSAGE error exit code

and attempt to return these consistently for all collie commands.

Signed-off-by: Chris Webb <[email protected]>

---
 collie/collie.c |   94 ++++++++++++++++++++++++++++--------------------------
 include/exits.h |   12 +++++++
 2 files changed, 61 insertions(+), 45 deletions(-)
 create mode 100644 include/exits.h

diff --git a/collie/collie.c b/collie/collie.c
index a0ac7f6..44eacd3 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -29,6 +29,7 @@
 #include "sheep.h"
 #include "net.h"
 #include "treeview.h"
+#include "exits.h"
 
 static char program_name[] = "collie";
 static const char *sdhost = "localhost";
@@ -183,7 +184,7 @@ static int cluster_format(int argc, char **argv)
 
        fd = connect_to(sdhost, sdport);
        if (fd < 0)
-               return -1;
+               return EXIT_SYSFAIL;
 
        gettimeofday(&tv, NULL);
 
@@ -201,15 +202,15 @@ static int cluster_format(int argc, char **argv)
 
        if (ret) {
                fprintf(stderr, "failed to connect\n");
-               return ret;
+               return EXIT_SYSFAIL;
        }
 
        if (rsp->result != SD_RES_SUCCESS) {
                fprintf(stderr, "%s\n", sd_strerror(rsp->result));
-               return 1;
+               return EXIT_FAILURE;
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int shutdown_sheepdog(void)
@@ -235,15 +236,15 @@ static int shutdown_sheepdog(void)
 
        if (ret) {
                fprintf(stderr, "failed to connect\n");
-               return ret;
+               return EXIT_SYSFAIL;
        }
 
        if (rsp->result != SD_RES_SUCCESS) {
                fprintf(stderr, "%s\n", sd_strerror(rsp->result));
-               return 1;
+               return EXIT_FAILURE;
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 typedef void (*vdi_parser_func_t)(uint32_t vid, char *name, char *tag,
@@ -615,7 +616,7 @@ static int node_list(int argc, char **argv)
                        printf("  %4d - %-20s\t%d\n", i, data, 
node_list_entries[i].nr_vnodes);
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int node_info(int argc, char **argv)
@@ -667,7 +668,7 @@ static int node_info(int argc, char **argv)
 
        if (success == 0) {
                fprintf(stderr, "cannot get information from any nodes\n");
-               return 1;
+               return EXIT_SYSFAIL;
        }
 
        parse_vdi(cal_total_vdi_size, SD_INODE_HEADER_SIZE, &total_vdi_size);
@@ -680,7 +681,7 @@ static int node_info(int argc, char **argv)
               (int)(((double)(total_size - total_avail) / total_size) * 100),
               vdi_size_str);
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static struct subcommand node_cmd[] = {
@@ -695,7 +696,7 @@ static int vdi_list(int argc, char **argv)
        
printf("------------------------------------------------------------------\n");
 
        parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL);
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int vdi_tree(int argc, char **argv)
@@ -704,7 +705,7 @@ static int vdi_tree(int argc, char **argv)
        parse_vdi(print_vdi_tree, SD_INODE_HEADER_SIZE, NULL);
        dump_tree();
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int vdi_graph(int argc, char **argv)
@@ -719,7 +720,7 @@ static int vdi_graph(int argc, char **argv)
        /* print a footer */
        printf("}\n");
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int vdi_delete(int argc, char **argv)
@@ -733,7 +734,7 @@ static int vdi_delete(int argc, char **argv)
 
        fd = connect_to(sdhost, sdport);
        if (fd < 0)
-               return -1;
+               return EXIT_SYSFAIL;
 
        memset(&hdr, 0, sizeof(hdr));
 
@@ -755,15 +756,18 @@ static int vdi_delete(int argc, char **argv)
 
        if (ret) {
                fprintf(stderr, "failed to connect\n");
-               return ret;
+               return EXIT_SYSFAIL;
        }
 
        if (rsp->result != SD_RES_SUCCESS) {
                fprintf(stderr, "%s: %s\n", vdiname, sd_strerror(rsp->result));
-               return 1;
+               if (rsp->result == SD_RES_NO_VDI)
+                       return EXIT_MISSING;
+               else
+                       return EXIT_FAILURE;
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int vdi_object(int argc, char **argv)
@@ -785,7 +789,7 @@ static int vdi_object(int argc, char **argv)
        vid = info.vid;
        if (vid == 0) {
                printf("No such vdi\n");
-               return 1;
+               return EXIT_MISSING;
        }
 
        if (idx == ~0) {
@@ -800,7 +804,7 @@ static int vdi_object(int argc, char **argv)
 
                if (idx >= MAX_DATA_OBJS) {
                        printf("The offset is too large!\n");
-                       exit(1);
+                       exit(EXIT_FAILURE);
                }
 
                parse_objs(vid_to_vdi_oid(vid), get_data_oid, &old_info);
@@ -819,7 +823,7 @@ static int vdi_object(int argc, char **argv)
                        printf("failed to read the inode object 0x%" PRIx32 
"\n", vid);
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
@@ -896,7 +900,7 @@ static int vdi_setattr(int argc, char **argv)
        key = argv[optind++];
        if (!key) {
                fprintf(stderr, "please specify the name of key\n");
-               return 1;
+               return EXIT_USAGE;
        }
 
        value = argv[optind++];
@@ -904,7 +908,7 @@ static int vdi_setattr(int argc, char **argv)
                value = malloc(SD_MAX_VDI_ATTR_VALUE_LEN);
                if (!value) {
                        fprintf(stderr, "failed to allocate memory\n");
-                       return 1;
+                       return EXIT_SYSFAIL;
                }
 
                offset = 0;
@@ -913,7 +917,7 @@ reread:
                           SD_MAX_VDI_ATTR_VALUE_LEN - offset);
                if (ret < 0) {
                        fprintf(stderr, "failed to read from stdin, %m\n");
-                       return 1;
+                       return EXIT_FAILURE;
                }
                if (ret > 0) {
                        offset += ret;
@@ -928,12 +932,13 @@ reread:
        if (ret) {
                if (ret == SD_RES_VDI_EXIST) {
                        fprintf(stderr, "the attribute already exists, %s\n", 
key);
+                       return EXIT_BUSY;
                } else if (ret == SD_RES_NO_OBJ) {
                        fprintf(stderr, "no such attribute, %s\n", key);
                } else
                        fprintf(stderr, "failed to find attr oid, %s\n",
                                sd_strerror(ret));
-               return 1;
+               return EXIT_MISSING;
        }
 
        oid = attr_oid;
@@ -976,16 +981,16 @@ reread:
 
                if (ret) {
                        fprintf(stderr, "failed to set attribute\n");
-                       return 1;
+                       return EXIT_FAILURE;
                }
                if (rsp->result != SD_RES_SUCCESS) {
                        fprintf(stderr, "failed to set attribute, %s\n",
                                sd_strerror(rsp->result));
-                       return 1;
+                       return EXIT_FAILURE;
                }
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int vdi_getattr(int argc, char **argv)
@@ -1002,7 +1007,7 @@ static int vdi_getattr(int argc, char **argv)
        key = argv[optind++];
        if (!key) {
                fprintf(stderr, "please specify the name of key\n");
-               return 1;
+               return EXIT_USAGE;
        }
 
        ret = find_vdi_attr_oid(vdiname, vdi_cmd_data.snapshot_tag,
@@ -1010,18 +1015,18 @@ static int vdi_getattr(int argc, char **argv)
                                &nr_copies, 0, 0);
        if (ret == SD_RES_NO_OBJ) {
                fprintf(stderr, "no such attribute, %s\n", key);
-               return 1;
+               return EXIT_MISSING;
        } else if (ret) {
                fprintf(stderr, "failed to find attr oid, %s\n",
                        sd_strerror(ret));
-               return 1;
+               return EXIT_MISSING;
        }
 
        oid = attr_oid;
        value = malloc(SD_MAX_VDI_ATTR_VALUE_LEN);
        if (!value) {
                fprintf(stderr, "failed to allocate memory\n");
-               return 1;
+               return EXIT_SYSFAIL;
        }
        for (i = 0; i < nr_copies; i++) {
                rlen = SD_MAX_VDI_ATTR_VALUE_LEN;
@@ -1054,13 +1059,13 @@ static int vdi_getattr(int argc, char **argv)
                        if (rsp->result == SD_RES_SUCCESS) {
                                printf("%s", value);
                                free(value);
-                               return 0;
+                               return EXIT_SUCCESS;
                        }
                }
        }
 out:
        free(value);
-       return 1;
+       return EXIT_FAILURE;
 }
 
 static struct subcommand vdi_cmd[] = {
@@ -1121,7 +1126,7 @@ static int cluster_info(int argc, char **argv)
 
        fd = connect_to(sdhost, sdport);
        if (fd < 0)
-               return 1;
+               return EXIT_SYSFAIL;
 
        memset(&hdr, 0, sizeof(hdr));
 
@@ -1135,7 +1140,7 @@ static int cluster_info(int argc, char **argv)
        close(fd);
 
        if (ret != 0)
-               return 1;
+               return EXIT_SYSFAIL;
 
        if (rsp->result == SD_RES_SUCCESS)
                printf("running\n");
@@ -1166,7 +1171,7 @@ static int cluster_info(int argc, char **argv)
                printf("]\n");
        }
 
-       return 0;
+       return EXIT_SUCCESS;
 }
 
 static int cluster_parser(int ch, char *opt)
@@ -1182,8 +1187,7 @@ static int cluster_parser(int ch, char *opt)
 
 static int cluster_shutdown(int argc, char **argv)
 {
-       shutdown_sheepdog();
-       return 0;
+       return shutdown_sheepdog();
 }
 
 static struct subcommand cluster_cmd[] = {
@@ -1251,7 +1255,7 @@ static unsigned long setup_command(char *cmd, char 
*subcmd)
 
        if (!found) {
                fprintf(stderr, "'%s' is not a valid command\n", cmd);
-               usage(1);
+               usage(EXIT_USAGE);
        }
 
        for (s = commands[i].sub; s->name; s++) {
@@ -1264,10 +1268,10 @@ static unsigned long setup_command(char *cmd, char 
*subcmd)
 
        if (!command_fn) {
                fprintf(stderr, "'%s' is not a valid subcommand\n", subcmd);
-               fprintf(stderr, "'%s' supports the following subcommand:\n", 
cmd);
+               fprintf(stderr, "'%s' supports the following subcommands:\n", 
cmd);
                for (s = commands[i].sub; s->name; s++)
                        fprintf(stderr, "%s\n", s->name);
-               exit(1);
+               exit(EXIT_USAGE);
        }
 
        return flags;
@@ -1300,13 +1304,13 @@ int main(int argc, char **argv)
                                command_help();
                        break;
                case '?':
-                       usage(1);
+                       usage(EXIT_USAGE);
                        break;
                default:
                        if (command_parser)
                                command_parser(ch, optarg);
                        else
-                               usage(1);
+                               usage(EXIT_USAGE);
                        break;
                }
        }
@@ -1318,13 +1322,13 @@ int main(int argc, char **argv)
                ret = update_node_list(SD_MAX_NODES, 0);
                if (ret < 0) {
                        fprintf(stderr, "failed to get node list\n");
-                       exit(1);
+                       exit(EXIT_SYSFAIL);
                }
        }
 
        if (flags & SUBCMD_FLAG_NEED_THIRD_ARG && argc == optind) {
                fprintf(stderr, "'%s %s' needs the third argument\n", argv[1], 
argv[2]);
-               exit(1);
+               exit(EXIT_USAGE);
        }
 
        return command_fn(argc, argv);
diff --git a/include/exits.h b/include/exits.h
new file mode 100644
index 0000000..2ad8327
--- /dev/null
+++ b/include/exits.h
@@ -0,0 +1,12 @@
+#ifndef __EXITS_H__
+#define __EXITS_H__
+
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#define EXIT_SYSFAIL 2
+#define EXIT_BUSY 3
+#define EXIT_FULL 4
+#define EXIT_MISSING 5
+#define EXIT_USAGE 64
+
+#endif
-- 
1.7.4.1

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to