diff --git a/agents/virt/client/options.c b/agents/virt/client/options.c index 9ecc76e6..5e05f75f 100644 --- a/agents/virt/client/options.c +++ b/agents/virt/client/options.c @@ -1,997 +1,997 @@ /* Copyright Red Hat, Inc. 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Local includes */ #include "xvm.h" #include "simple_auth.h" #include "mcast.h" #include "tcp_listener.h" #include "options.h" #define SCHEMA_COMPAT '\xfe' /* Assignment functions */ static inline void assign_debug(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) { /* GNU getopt sets optarg to NULL for options w/o a param We rely on this here... */ args->debug++; return; } args->debug = atoi(value); if (args->debug < 0) { args->debug = 1; } } static inline void assign_family(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (!strcasecmp(value, "ipv4")) { args->net.family = PF_INET; } else if (!strcasecmp(value, "ipv6")) { args->net.family = PF_INET6; } else if (!strcasecmp(value, "auto")) { args->net.family = 0; } else { printf("Unsupported family: '%s'\n", value); args->flags |= F_ERR; } } static inline void assign_address(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (args->net.addr) free(args->net.addr); args->net.addr = strdup(value); } static inline void assign_ip_address(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (args->net.ipaddr) free(args->net.ipaddr); args->net.ipaddr = strdup(value); } static inline void assign_channel_address(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (args->serial.address) free(args->serial.address); args->serial.address = strdup(value); } static inline void assign_port(fence_virt_args_t *args, struct arg_info *arg, char *value) { char *p; int ret; if (!value) return; ret = strtol(value, &p, 0); if (ret <= 0 || ret >= 65536 || *p != '\0') { printf("Invalid port: '%s'\n", value); args->flags |= F_ERR; } else args->net.port = ret; } static inline void assign_cid(fence_virt_args_t *args, struct arg_info *arg, char *value) { char *p; unsigned long ret; if (!value) { args->net.cid = 2; return; } ret = strtoul(value, &p, 0); if (!p || *p != '\0' || ret < 2 || ret >= 0xffffffff) { printf("Invalid CID: '%s'\n", value); args->flags |= F_ERR; } else args->net.cid = ret; } static inline void assign_interface(fence_virt_args_t *args, struct arg_info *arg, char *value) { int ret; if (!value) return; ret = if_nametoindex(value); if (ret <= 0) { printf("Invalid interface: %s: %s\n", value, strerror(errno)); args->net.ifindex = 0; } args->net.ifindex = ret; } static inline void assign_retrans(fence_virt_args_t *args, struct arg_info *arg, char *value) { char *p; int ret; if (!value) return; ret = strtol(value, &p, 0); if (ret <= 0 || *p != '\0') { printf("Invalid retransmit time: '%s'\n", value); args->flags |= F_ERR; } else args->retr_time = ret; } static inline void assign_hash(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (!strcasecmp(value, "none")) { args->net.hash = HASH_NONE; } else if (!strcasecmp(value, "sha1")) { args->net.hash = HASH_SHA1; } else if (!strcasecmp(value, "sha256")) { args->net.hash = HASH_SHA256; } else if (!strcasecmp(value, "sha512")) { args->net.hash = HASH_SHA512; } else { printf("Unsupported hash: %s\n", value); args->flags |= F_ERR; } } static inline void assign_auth(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (!strcasecmp(value, "none")) { args->net.auth = AUTH_NONE; } else if (!strcasecmp(value, "sha1")) { args->net.auth = AUTH_SHA1; } else if (!strcasecmp(value, "sha256")) { args->net.auth = AUTH_SHA256; } else if (!strcasecmp(value, "sha512")) { args->net.auth = AUTH_SHA512; } else { printf("Unsupported auth type: %s\n", value); args->flags |= F_ERR; } } static inline void assign_key(fence_virt_args_t *args, struct arg_info *arg, char *value) { struct stat st; if (!value) return; if (args->net.key_file) free(args->net.key_file); args->net.key_file = strdup(value); if (stat(value, &st) == -1) { printf("Invalid key file: '%s' (%s)\n", value, strerror(errno)); args->flags |= F_ERR; } } static inline void assign_op(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; if (!strcasecmp(value, "null")) { args->op = FENCE_NULL; } else if (!strcasecmp(value, "on")) { args->op = FENCE_ON; } else if (!strcasecmp(value, "off")) { args->op = FENCE_OFF; } else if (!strcasecmp(value, "reboot")) { args->op = FENCE_REBOOT; } else if (!strcasecmp(value, "status")) { args->op = FENCE_STATUS; } else if (!strcasecmp(value, "monitor")) { args->op = FENCE_DEVSTATUS; } else if (!strcasecmp(value, "list") || !strcasecmp(value, "list-status")) { args->op = FENCE_HOSTLIST; } else if (!strcasecmp(value, "metadata")) { args->op = FENCE_METADATA; } else if (!strcasecmp(value, "validate-all")) { args->op = FENCE_VALIDATEALL; } else { printf("Unsupported operation: %s\n", value); args->flags |= F_ERR; } } static inline void assign_device(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; args->serial.device = strdup(value); } static inline void assign_params(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) return; args->serial.speed = strdup(value); } static inline void assign_domain(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (args->domain) { printf("Domain/UUID may not be specified more than once\n"); args->flags |= F_ERR; return; } if (!value) return; args->domain = strdup(value); if (strlen(value) <= 0) { printf("Invalid domain name\n"); args->flags |= F_ERR; } if (strlen(value) >= MAX_DOMAINNAME_LENGTH) { errno = ENAMETOOLONG; printf("Invalid domain name: '%s' (%s)\n", value, strerror(errno)); args->flags |= F_ERR; } } static inline void assign_uuid_lookup(fence_virt_args_t *args, struct arg_info *arg, char *value) { if (!value) { /* GNU getopt sets optarg to NULL for options w/o a param We rely on this here... */ args->flags |= F_USE_UUID; return; } args->flags |= ( !!atoi(value) ? F_USE_UUID : 0); } static inline void assign_timeout(fence_virt_args_t *args, struct arg_info *arg, char *value) { char *p; int ret; if (!value) return; ret = strtol(value, &p, 0); if (ret <= 0 || *p != '\0') { printf("Invalid timeout: '%s'\n", value); args->flags |= F_ERR; } else args->timeout = ret; } static inline void assign_delay(fence_virt_args_t *args, struct arg_info *arg, char *value) { char *p; int ret; if (!value) return; ret = strtol(value, &p, 0); if (ret < 0 || *p != '\0') { printf("Invalid delay: '%s'\n", value); args->flags |= F_ERR; } else args->delay = ret; } static inline void assign_help(fence_virt_args_t *args, struct arg_info *arg, char *value) { args->flags |= F_HELP; } static inline void assign_version(fence_virt_args_t *args, struct arg_info *arg, char *value) { args->flags |= F_VERSION; } static void print_desc_xml(const char *desc) { const char *d; for (d = desc; *d; d++) { switch (*d) { case '<': printf("<"); break; case '>': printf(">"); break; default: printf("%c", *d); } } } /** ALL valid command line and stdin arguments for this fencing agent */ static struct arg_info _arg_info[] = { { '\xff', NULL, "agent", NULL, 0, 0, "string", NULL, "Not user serviceable", NULL }, { '\xff', NULL, "self", NULL, 0, 0, "string", NULL, "Not user serviceable", NULL }, { '\xff', NULL, "nodename", NULL, 0, 0, "string", NULL, "Not user serviceable", NULL }, { 'd', "-d", "debug", NULL, 0, 0, "boolean", NULL, "Specify (stdin) or increment (command line) debug level", assign_debug }, { 'i', "-i ", "ip_family", NULL, 0, 0, "string", "auto", "IP Family ([auto], ipv4, ipv6)", assign_family }, { 'a', "-a
", "multicast_address", NULL, 0, 0, "string", NULL, "Multicast address (default=" IPV4_MCAST_DEFAULT " / " IPV6_MCAST_DEFAULT ")", assign_address }, { 'T', "-T
", "ipaddr", NULL, 0, 0, "string", "127.0.0.1", "IP address to connect to in TCP mode (default=" IPV4_TCP_ADDR_DEFAULT " / " IPV6_TCP_ADDR_DEFAULT ")", assign_ip_address }, { 'S', "-S ", "vsock", NULL, 0, 0, "int", "2", "vm socket CID to connect to in vsock mode", assign_cid }, { 'A', "-A
", "channel_address", NULL, 0, 0, "string", "10.0.2.179", "VM Channel IP address (default=" DEFAULT_CHANNEL_IP ")", assign_channel_address }, { 'p', "-p ", "ipport", NULL, 0, 0, "string", "1229", "TCP, Multicast, VMChannel, or VM socket port (default=1229)", assign_port }, { 'I', "-I ", "interface", NULL, 0, 0, "string", NULL, "Network interface name to listen on", assign_interface }, { 'r', "-r ", "retrans", NULL, 0, 0, "string", "20", "Multicast retransmit time (in 1/10sec; default=20)", assign_retrans }, { 'c', "-c ", "hash", NULL, 0, 0, "string", "sha256", "Packet hash strength (none, sha1, [sha256], sha512)", assign_hash }, { 'C', "-C ", "auth", NULL, 0, 0, "string", "sha256", "Authentication (none, sha1, [sha256], sha512)", assign_auth }, { 'k', "-k ", "key_file", NULL, 0, 0, "string", DEFAULT_KEY_FILE, "Shared key file (default=" DEFAULT_KEY_FILE ")", assign_key }, { 'D', "-D ", "serial_device", NULL, 0, 0, "string", NULL, "Serial device (default=" DEFAULT_SERIAL_DEVICE ")", assign_device }, { 'P', "-P ", "serial_params", NULL, 0, 0, "string", DEFAULT_SERIAL_SPEED, "Serial Parameters (default=" DEFAULT_SERIAL_SPEED ")", assign_params }, { '\xff', NULL, "option", /* Deprecated */ NULL, 0, 0, "string", "reboot", "Fencing option (null, off, on, [reboot], status, list, list-status, monitor, validate-all, metadata)", assign_op }, { 'o', "-o ", "action", NULL, 0, 0, "string", "reboot", "Fencing action (null, off, on, [reboot], status, list, list-status, monitor, validate-all, metadata)", assign_op }, { 'n', "-n ", "plug", "port", 0, 0, "string", NULL, "Virtual Machine (domain name) to fence", assign_domain }, { 'H', "-H ", "port", NULL, 1, 0, "string", NULL, "Virtual Machine (domain name) to fence", assign_domain }, { SCHEMA_COMPAT, NULL, "domain", NULL, 0, 0, "string", NULL, "Virtual Machine (domain name) to fence (deprecated; use port)", assign_domain }, { 'u', "-u", "use_uuid", NULL, 0, 0, "string", "0", "Treat [domain] as UUID instead of domain name. This is provided for compatibility with older fence_xvmd installations.", assign_uuid_lookup }, { 't', "-t ", "timeout", NULL, 0, 0, "string", "30", "Fencing timeout (in seconds; default=30)", assign_timeout }, { 'h', "-h", NULL, NULL, 0, 0, "boolean", "0", "Help", assign_help }, { '?', "-?", NULL, NULL, 0, 0, "boolean", "0", "Help (alternate)", assign_help }, { 'w', "-w ", "delay", NULL, 0, 0, "string", "0", "Fencing delay (in seconds; default=0)", assign_delay }, { 'V', "-V", NULL, NULL, 0, 0, "boolean", "0", "Display version and exit", assign_version }, /* Terminator */ { 0, NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL } }; static struct arg_info * find_arg_by_char(char arg) { int x = 0; for (x = 0; _arg_info[x].opt != 0; x++) { if (_arg_info[x].opt == arg) return &_arg_info[x]; } return NULL; } static struct arg_info * find_arg_by_string(char *arg) { int x = 0; for (x = 0; _arg_info[x].opt != 0; x++) { if (!_arg_info[x].stdin_opt) continue; if (!strcasecmp(_arg_info[x].stdin_opt, arg)) return &_arg_info[x]; } return NULL; } /* ============================================================= */ /** Initialize an args structure. @param args Pointer to args structure to initialize. */ void args_init(fence_virt_args_t *args) { args->domain = NULL; //args->uri = NULL; args->op = FENCE_REBOOT; args->net.key_file = strdup(DEFAULT_KEY_FILE); args->net.hash = DEFAULT_HASH; args->net.auth = DEFAULT_AUTH; args->net.addr = NULL; args->net.ipaddr = NULL; args->net.cid = 0; args->net.port = DEFAULT_MCAST_PORT; args->net.ifindex = 0; args->net.family = 0; /* auto */ args->serial.device = NULL; args->serial.speed = strdup(DEFAULT_SERIAL_SPEED); args->serial.address = strdup(DEFAULT_CHANNEL_IP); args->timeout = 30; args->retr_time = 20; args->flags = 0; args->debug = 0; args->delay = 0; } #define _pr_int(piece) printf(" %s = %d\n", #piece, piece) #define _pr_str(piece) printf(" %s = %s\n", #piece, piece) /** Prints out the contents of an args structure for debugging. @param args Pointer to args structure to print out. */ void args_print(fence_virt_args_t *args) { printf("-- args @ %p --\n", args); _pr_str(args->domain); _pr_int(args->op); _pr_int(args->mode); _pr_int(args->debug); _pr_int(args->timeout); _pr_int(args->delay); _pr_int(args->retr_time); _pr_int(args->flags); _pr_str(args->net.addr); _pr_str(args->net.ipaddr); _pr_int(args->net.cid); _pr_str(args->net.key_file); _pr_int(args->net.port); _pr_int(args->net.hash); _pr_int(args->net.auth); _pr_int(args->net.family); _pr_int(args->net.ifindex); _pr_str(args->serial.device); _pr_str(args->serial.speed); _pr_str(args->serial.address); printf("-- end args --\n"); } /** Print out arguments and help information based on what is allowed in the getopt string optstr. @param progname Program name. @param optstr Getopt(3) style options string @param print_stdin 0 = print command line options + description, 1 = print fence-style stdin args + description */ static char * find_rev(const char *start, char *curr, char c) { while (curr > start) { if (*curr == c) return curr; --curr; } return NULL; } static void output_help_text(int arg_width, int help_width, const char *arg, const char *desc) { char out_buf[4096]; char *p, *start; const char *arg_print = arg; int len; memset(out_buf, 0, sizeof(out_buf)); strncpy(out_buf, desc, sizeof(out_buf) - 1); start = out_buf; do { p = NULL; len = strlen(start); if (len > help_width) { p = start + help_width; p = find_rev(start, p, ' '); if (p) { *p = 0; p++; } } printf(" %*.*s %*.*s\n", -arg_width, arg_width, arg_print, -help_width, help_width, start); if (!p) return; if (arg == arg_print) arg_print = " "; start = p; } while(1); } void args_usage(char *progname, const char *optstr, int print_stdin) { int x; struct arg_info *arg; if (!print_stdin) { if (progname) { printf("usage: %s [args]\n", progname); } else { printf("usage: fence_virt [args]\n"); } } for (x = 0; x < strlen(optstr); x++) { arg = find_arg_by_char(optstr[x]); if (!arg || arg->deprecated) continue; if (print_stdin) { if (arg && arg->stdin_opt) output_help_text(20, 55, arg->stdin_opt, arg->desc); } else { output_help_text(20, 55, arg->opt_desc, arg->desc); } } printf("\n"); } void args_metadata(char *progname, const char *optstr) { int x; struct arg_info *arg; printf("\n"); printf("\n", basename(progname)); printf("%s is an I/O Fencing agent which can be used with " "virtual machines.\n", basename(progname)); printf("\n"); for (x = 0; x < strlen(optstr); x++) { arg = find_arg_by_char(optstr[x]); if (!arg) continue; if (!arg->stdin_opt) continue; if (arg->obsoletes) printf("\t\n", arg->stdin_opt, arg->obsoletes); else if (arg->deprecated) printf("\t\n", arg->stdin_opt, arg->deprecated); else printf("\t\n", arg->stdin_opt); printf("\t\t\n",arg->opt); if (arg->default_value) { printf("\t\t\n", arg->content_type, arg->default_value); } else { printf("\t\t\n", arg->content_type); } printf("\t\t"); print_desc_xml(arg->desc); printf("\n"); printf("\t\n"); } for (x = 0; _arg_info[x].opt != 0; x++) { if (_arg_info[x].opt != SCHEMA_COMPAT) continue; arg = &_arg_info[x]; printf("\t\n",arg->stdin_opt); printf("\t\t\n"); if (arg->default_value) { printf("\t\t\n", arg->content_type, arg->default_value); } else { printf("\t\t\n", arg->content_type); } printf("\t\t"); print_desc_xml(arg->desc); printf("\n"); printf("\t\n"); } printf("\n"); printf("\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\t\n"); printf("\n"); printf("\n"); } /** Remove leading and trailing whitespace from a line of text. @param line Line to clean up @param linelen Max size of line @return 0 on success, -1 on failure */ static int cleanup(char *line, size_t linelen) { char *p; int x; /* Remove leading whitespace. */ p = line; for (x = 0; x <= linelen; x++) { switch (line[x]) { case '\t': case ' ': break; case '\n': case '\r': return -1; default: goto eol; } } eol: /* Move the remainder down by as many whitespace chars as we chewed up */ if (x) memmove(p, &line[x], linelen-x); /* Remove trailing whitespace. */ for (x=0; x <= linelen; x++) { switch(line[x]) { case '\t': case ' ': case '\r': case '\n': line[x] = 0; case 0: /* End of line */ return 0; } } return -1; } /** Parse args from stdin and assign to the specified args structure. @param optstr Command line option string in getopt(3) format @param args Args structure to fill in. */ void args_get_stdin(const char *optstr, fence_virt_args_t *args) { char in[256]; char *name, *val; struct arg_info *arg; while (fgets(in, sizeof(in), stdin)) { if (in[0] == '#') continue; if (cleanup(in, sizeof(in)) == -1) continue; name = in; if ((val = strchr(in, '='))) { *val = 0; ++val; } arg = find_arg_by_string(name); if (!arg || (arg->opt != '\xff' && arg->opt != SCHEMA_COMPAT && !strchr(optstr, arg->opt))) { fprintf(stderr, "Parse error: Ignoring unknown option '%s'\n", name); continue; } if (arg->assign) arg->assign(args, arg, val); } } /** Parse args from stdin and assign to the specified args structure. @param optstr Command line option string in getopt(3) format @param args Args structure to fill in. */ void args_get_getopt(int argc, char **argv, const char *optstr, fence_virt_args_t *args) { int opt; struct arg_info *arg; while ((opt = getopt(argc, argv, optstr)) != EOF) { arg = find_arg_by_char(opt); if (!arg) { args->flags |= F_ERR; continue; } if (arg->assign) arg->assign(args, arg, optarg); } } void args_finalize(fence_virt_args_t *args) { char *addr = NULL; if (!args->net.addr) { switch(args->net.family) { case 0: case PF_INET: - addr = IPV4_MCAST_DEFAULT; + addr = (char *)IPV4_MCAST_DEFAULT; break; case PF_INET6: - addr = IPV6_MCAST_DEFAULT; + addr = (char *)IPV6_MCAST_DEFAULT; break; default: args->flags |= F_ERR; break; } } if (!args->net.addr) args->net.addr = addr; if (!args->net.addr) { printf("No multicast address available\n"); args->flags |= F_ERR; } if (!args->net.addr) return; if (args->net.family) return; /* Set family */ if (strchr(args->net.addr, ':')) args->net.family = PF_INET6; if (strchr(args->net.addr, '.')) args->net.family = PF_INET; if (!args->net.family) { printf("Could not determine address family\n"); args->flags |= F_ERR; } } diff --git a/agents/virt/include/options.h b/agents/virt/include/options.h index 6c5d7f1f..6e2c1c1b 100644 --- a/agents/virt/include/options.h +++ b/agents/virt/include/options.h @@ -1,99 +1,99 @@ /* Copyright Red Hat, Inc. 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _XVM_OPTIONS_H #define _XVM_OPTIONS_H typedef enum { F_FOREGROUND = 0x1, F_NOCCS = 0x2, F_ERR = 0x4, F_HELP = 0x8, F_USE_UUID = 0x10, F_VERSION = 0x20, F_CCSERR = 0x40, F_CCSFAIL = 0x80, F_NOCLUSTER = 0x100 } arg_flags_t; typedef enum { MODE_MULTICAST = 0, /*MODE_BROADCAST = 1,*/ MODE_SERIAL = 2, MODE_VMCHANNEL = 3, MODE_TCP = 4, MODE_VSOCK = 5 } client_mode_t; typedef struct { char *domain; fence_cmd_t op; client_mode_t mode; int debug; int timeout; int delay; int retr_time; arg_flags_t flags; struct network_args { char *addr; char *ipaddr; char *key_file; uint32_t cid; int port; fence_hash_t hash; fence_auth_type_t auth; int family; unsigned int ifindex; } net; struct serial_args { char *device; /* Serial device */ char *speed; char *address; /* vmchannel IP */ } serial; } fence_virt_args_t; /* Private structure for commandline / stdin fencing args */ struct arg_info { - char opt; - char *opt_desc; - char *stdin_opt; - char *obsoletes; + const char opt; + const char *opt_desc; + const char *stdin_opt; + const char *obsoletes; int deprecated; int eh; - char *content_type; - char *default_value; - char *desc; + const char *content_type; + const char *default_value; + const char *desc; void (*assign)(fence_virt_args_t *, struct arg_info *, char *); }; /* Get options */ void args_init(fence_virt_args_t *args); void args_finalize(fence_virt_args_t *args); void args_get_getopt(int argc, char **argv, const char *optstr, fence_virt_args_t *args); void args_get_stdin(const char *optstr, fence_virt_args_t *args); void args_get_ccs(const char *optstr, fence_virt_args_t *args); void args_usage(char *progname, const char *optstr, int print_stdin); void args_print(fence_virt_args_t *args); void args_metadata(char *progname, const char *optstr); #endif diff --git a/configure.ac b/configure.ac index 5d1910cc..33b54143 100644 --- a/configure.ac +++ b/configure.ac @@ -1,646 +1,646 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) # TODO: port .gitarchiver AC_INIT([fence-agents], [m4_esyscmd([make/git-version-gen .tarball-version])], [developers@clusterlabs.org]) AC_CONFIG_AUX_DIR([.]) # Don't let AC_PROC_CC (invoked by AC_USE_SYSTEM_EXTENSIONS) replace # undefined CFLAGS with -g -O2, overriding our special OPT_CFLAGS. : ${CFLAGS=""} AC_USE_SYSTEM_EXTENSIONS AM_INIT_AUTOMAKE([1.13 dist-bzip2 dist-xz color-tests -Wno-portability subdir-objects]) # Sanitize path if test "$prefix" = "NONE"; then prefix="/usr" if test "$localstatedir" = "\${prefix}/var"; then localstatedir="/var" fi if test "$sysconfdir" = "\${prefix}/etc"; then sysconfdir="/etc" fi if test "$libdir" = "\${exec_prefix}/lib"; then if test -e /usr/lib64; then libdir="/usr/lib64" else libdir="/usr/lib" fi fi fi case $exec_prefix in NONE) exec_prefix=$prefix;; prefix) exec_prefix=$prefix;; esac # It is necessary to have this done before libtool does linker detection. # See also: https://github.com/kronosnet/kronosnet/issues/107 # --as-needed: Modern systems have builtin ceil() making -lm superfluous but # AC_SEARCH_LIBS can't detect this because it tests with a false prototype AX_CHECK_LINK_FLAG([-Wl,--enable-new-dtags], [AM_LDFLAGS=-Wl,--enable-new-dtags], [AC_MSG_ERROR(["Linker support for --enable-new-dtags is required"])]) AX_CHECK_LINK_FLAG([-Wl,--as-needed], [AM_LDFLAGS="$AM_LDFLAGS -Wl,--as-needed"]) VIRT_AM_LDFLAGS="$AM_LDFLAGS -fPIC -fPIE -Wl,-z,now" AC_SUBST([VIRT_AM_LDFLAGS]) saved_LDFLAGS="$LDFLAGS" LDFLAGS="$VIRT_AM_LDFLAGS $LDFLAGS" LT_PREREQ([2.2.6]) LT_INIT LDFLAGS="$saved_LDFLAGS" VIRT_AM_CFLAGS="-fPIC -fPIE -I\$(top_srcdir)/agents/virt/include -Wformat=2 -Wstrict-prototypes -Wno-unused -D_GNU_SOURCE" AC_SUBST([VIRT_AM_CFLAGS]) VIRT_COMMON_LDFLAGS="-Wl,-wrap,syslog,-wrap,closelog" AC_SUBST([VIRT_COMMON_LDFLAGS]) VIRT_COMMON_LIBS="-Wl,-Bstatic -L\$(top_builddir)/agents/virt/common -lfence_virt -Wl,-Bdynamic" AC_SUBST([VIRT_COMMON_LIBS]) VIRT_CONFIG_LIBS="-L\$(top_builddir)/agents/virt/config -lsimpleconfig" AC_SUBST([VIRT_CONFIG_LIBS]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([lib/fencing.py.py]) AC_CONFIG_HEADERS([make/config.h]) AC_CANONICAL_HOST AC_PROG_LIBTOOL AC_LANG([C]) # Checks for programs. # check stolen from gnulib/m4/gnu-make.m4 if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then AC_MSG_ERROR([you don't seem to have GNU make; it is required]) fi AC_PROG_CC AM_PROG_CC_C_O AC_PROG_GCC_TRADITIONAL AC_PROG_LN_S AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_AWK AC_PROG_CXX AC_PROG_RANLIB AC_PROG_YACC AC_PROG_LEX PKG_PROG_PKG_CONFIG ## local helper functions # this function checks if CC support options passed as # args. Global CFLAGS are ignored during this test. cc_supports_flag() { local CFLAGS="$@" AC_MSG_CHECKING([whether $CC supports "$@"]) AC_COMPILE_IFELSE([int main(){return 0;}], [RC=0; AC_MSG_RESULT([yes])], [RC=1; AC_MSG_RESULT([no])]) return $RC } # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_TIME AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h syslog.h termios.h unistd.h libintl.h limits.h netdb.h stddef.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE AC_C_CONST AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT32_T AC_TYPE_OFF_T AC_TYPE_SIGNAL # Checks for library functions. AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_CLOSEDIR_VOID AC_FUNC_MEMCMP AC_FUNC_SELECT_ARGTYPES AC_FUNC_STAT AC_CHECK_FUNCS([alarm atexit bzero dup2 memmove memset select socket strcasecmp strchr strdup strerror strtol gettimeofday]) # local options AC_ARG_ENABLE([debug], [ --enable-debug enable debug build. ], [ default="no" ]) AC_ARG_WITH([fenceagentslibdir], [ --with-fenceagentslibdir=PATH installation path for fence library. ], [ FENCEAGENTSLIBDIR="$withval" ], [ FENCEAGENTSLIBDIR="${datadir}/fence" ]) AC_ARG_WITH([default-config-dir], [ --with-default-config-dir=DIR cluster config directory. ], [ DEFAULT_CONFIG_DIR="$withval" ], [ DEFAULT_CONFIG_DIR="$sysconfdir/cluster" ]) AC_ARG_WITH([default-config-file], [ --with-default-config-file=FILE cluster config file. ], [ DEFAULT_CONFIG_FILE="$withval" ], [ DEFAULT_CONFIG_FILE="cluster.conf" ]) AC_ARG_WITH([agents], [ --with-agents=LIST list of agents to build/ship (default: all). ], [ AGENTS_LIST="$withval" ], [ AGENTS_LIST="all" ]) if test "x$AGENTS_LIST" = x; then AC_ERROR([No agents selected]) fi FENCE_KDUMP=0 if echo "$AGENTS_LIST" | grep -q -E "all|kdump"; then case "$host_os" in *bsd*) ;; *) FENCE_KDUMP=1 ;; esac AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s/kdump( |$)//") fi FENCE_MANUAL=0 if echo "$AGENTS_LIST" | grep -q -E "all|manual"; then FENCE_MANUAL=1 AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s/manual( |$)//") fi FENCE_MPATH=0 if echo "$AGENTS_LIST" | grep -q -E "all|mpath"; then FENCE_MPATH=1 fi FENCE_SCSI=0 if echo "$AGENTS_LIST" | grep -q -E "all|scsi"; then FENCE_SCSI=1 fi FENCE_ZVM=0 if echo "$AGENTS_LIST" | grep -q -E "all|zvm( |$)"; then FENCE_ZVM=1 fi FENCE_VIRT=0 if echo "$AGENTS_LIST" | grep -q -E "all|virt( |$)"; then FENCE_VIRT=1 # Checks for libraries. AX_PTHREAD(,[AC_MSG_ERROR([POSIX threads support is required])]) PKG_CHECK_MODULES([nss], [nss]) PKG_CHECK_MODULES([xml2], [libxml-2.0]) PKG_CHECK_MODULES([uuid], [uuid]) saved_LIBS="$LIBS" LIBS= AC_SEARCH_LIBS([dlopen], [dl dld], , [AC_MSG_ERROR([dlopen not found])]) AC_SUBST([dl_LIBS], [$LIBS]) LIBS="$saved_LIBS" fi if test "x$AGENTS_LIST" != xall; then for j in $AGENTS_LIST; do if ! test -f agents/$j/fence_$j*.py; then AC_ERROR([Agent $j does not exists]) fi AGENTS_LIST=`echo "$AGENTS_LIST" | sed -E -e "s#$j([^_/]|$)#$j/fence_$j\1#g" -e "s#zvm/fence_zvm( |$)#zvm/fence_zvmip\1#g"` done fi if test "x$AGENTS_LIST" = xall; then AGENTS_LIST=`find $srcdir/agents -mindepth 2 -maxdepth 2 -name 'fence_*.py' -print0 | xargs -0 | sed -E -e 's#[^ ]*/agents/##g' -e 's#lib/[A-Za-z_.]*( |$)##g' -e 's#nss_wrapper/[A-Za-z_.]*( |$)##g' -e 's#autodetect/[A-Za-z_.]*( |$)##g'` fi XENAPILIB=0 if echo "$AGENTS_LIST" | grep -q xenapi; then XENAPILIB=1 fi ## random vars LOGDIR=${localstatedir}/log/cluster CLUSTERVARRUN=${localstatedir}/run/cluster CLUSTERDATA=${datadir}/cluster AC_PATH_PROGS(XMLLINT, xmllint) AM_CONDITIONAL(BUILD_DOC, test "x$XMLLINT" != "x" ) if test "x$XMLLINT" = "x"; then AC_MSG_WARN([xmllint not installed, unable to (re-)build manual pages]) exit 1 fi AC_SUBST(XMLLINT) AC_PATH_PROGS(XSLTPROC, xsltproc) AM_CONDITIONAL(BUILD_DOC, test "x$XSLTPROC" != "x" ) if test "x$XSLTPROC" = "x"; then AC_MSG_WARN([xsltproc not installed, unable to (re-)build manual pages]) exit 1 fi AC_SUBST(XSLTPROC) AM_PATH_PYTHON if test -z "$PYTHON"; then echo "*** Essential program python not found" 1>&2 exit 1 fi dnl Ensure PYTHON is an absolute path AC_PATH_PROG([PYTHON], [$PYTHON]) AC_PYTHON_MODULE(pexpect, 1) AC_PYTHON_MODULE(pycurl, 1) AC_PYTHON_MODULE(requests, 1) if echo "$AGENTS_LIST" | grep -q amt_ws; then AC_PYTHON_MODULE(pywsman) if test "x${HAVE_PYMOD_PYWSMAN}" != xyes; then AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s#amt_ws/fence_amt_ws.py( |$)##") AC_MSG_WARN("Not building fence_amt_ws") fi fi if echo "$AGENTS_LIST" | grep -q aws; then AC_PYTHON_MODULE(boto3) if test "x${HAVE_PYMOD_BOTO3}" != xyes; then AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s#aws/fence_aws.py( |$)##") AC_MSG_WARN("Not building fence_aws") fi fi if echo "$AGENTS_LIST" | grep -q -E "ovh|vmware_soap"; then AC_PYTHON_MODULE(suds) if test "x${HAVE_PYMOD_SUDS}" != xyes; then AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s#(ovh/fence_ovh|vmware_soap/fence_vmware_soap).py( |$)##g") AC_MSG_WARN("Not building fence_ovh and fence_vmware_soap") fi fi if echo "$AGENTS_LIST" | grep -q gce; then AC_PYTHON_MODULE(googleapiclient) AC_PYTHON_MODULE(oauth2client) if test "x${HAVE_PYMOD_GOOGLEAPICLIENT}" != xyes; then AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s#gce/fence_gce.py( |$)##") AC_MSG_WARN("Not building fence_ovh and fence_gce") fi fi ## path to 3rd-party binaries AC_PATH_PROG([IPMITOOL_PATH], [ipmitool], [/usr/bin/ipmitool]) AC_PATH_PROG([OPENSTACK_PATH], [openstack], [/usr/bin/openstack]) AC_PATH_PROG([AMTTOOL_PATH], [amttool], [/usr/bin/amttool]) AC_PATH_PROG([GNUTLSCLI_PATH], [gnutlscli], [/usr/bin/gnutls-cli]) AC_PATH_PROG([COROSYNC_CMAPCTL_PATH], [corosync-cmapctl], [/usr/sbin/corosync-cmapctl]) AC_PATH_PROG([SG_PERSIST_PATH], [sg_persist], [/usr/bin/sg_persist]) AC_PATH_PROG([SG_TURS_PATH], [sg_turs], [/usr/bin/sg_turs]) AC_PATH_PROG([VGS_PATH], [vgs], [/usr/sbin/vgs]) AC_PATH_PROG([SUDO_PATH], [sudo], [/usr/bin/sudo]) AC_PATH_PROG([SSH_PATH], [ssh], [/usr/bin/ssh]) AC_PATH_PROG([TELNET_PATH], [telnet], [/usr/bin/telnet]) AC_PATH_PROG([MPATH_PATH], [mpathpersist], [/usr/sbin/mpathpersist]) AC_PATH_PROG([SBD_PATH], [sbd], [/sbin/sbd]) AC_PATH_PROG([SUDO_PATH], [sudo], [/usr/bin/sudo]) AC_PATH_PROG([SNMPWALK_PATH], [snmpwalk], [/usr/bin/snmpwalk]) AC_PATH_PROG([SNMPSET_PATH], [snmpset], [/usr/bin/snmpset]) AC_PATH_PROG([SNMPGET_PATH], [snmpget], [/usr/bin/snmpget]) AC_PATH_PROG([NOVA_PATH], [nova], [/usr/bin/nova]) AC_PATH_PROG([POWERMAN_PATH], [powerman], [/usr/bin/powerman]) AC_PATH_PROG([PING_CMD], [ping]) AC_PATH_PROG([PING6_CMD], [ping6]) AC_PATH_PROG([PING4_CMD], [ping4]) if test "x${ac_cv_path_PING_CMD}" = x; then # assume multicall-ping just not available in build-environment PING_CMD="/bin/ping" PING4_CMD="/bin/ping -4" PING6_CMD="/bin/ping -6" elif test "x${ac_cv_path_PING6_CMD}" = x; then # just IPv4 PING4_CMD="${ac_cv_path_PING_CMD}" elif test -L ${ac_cv_path_PING6_CMD}; then # assume multicall-ping PING4_CMD="${ac_cv_path_PING_CMD} -4" else # ping is just IPv4 PING4_CMD="${ac_cv_path_PING_CMD}" fi ## do subst AC_SUBST([DEFAULT_CONFIG_DIR]) AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR], "$(eval echo ${DEFAULT_CONFIG_DIR})", [Default config directory]) AC_SUBST([DEFAULT_CONFIG_FILE]) AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE], "$(eval echo ${DEFAULT_CONFIG_FILE})", [Default config file]) AC_SUBST([LOGDIR]) AC_DEFINE_UNQUOTED([LOGDIR], "$(eval echo ${LOGDIR})", [Default logging directory]) AC_SUBST([CLUSTERVARRUN]) AC_DEFINE_UNQUOTED([CLUSTERVARRUN], "$(eval echo ${CLUSTERVARRUN})", [Default cluster var/run directory]) AC_SUBST([CLUSTERDATA]) AC_SUBST([FENCEAGENTSLIBDIR]) AC_SUBST([SNMPBIN]) AC_SUBST([AGENTS_LIST]) AM_CONDITIONAL(BUILD_FENCE_KDUMP, test $FENCE_KDUMP -eq 1) AM_CONDITIONAL(BUILD_FENCE_MANUAL, test $FENCE_MANUAL -eq 1) AM_CONDITIONAL(BUILD_FENCE_MPATH, test $FENCE_MPATH -eq 1) AM_CONDITIONAL(BUILD_FENCE_SCSI, test $FENCE_SCSI -eq 1) AM_CONDITIONAL(BUILD_FENCE_ZVM, test $FENCE_ZVM -eq 1) AM_CONDITIONAL(BUILD_FENCE_VIRT, test $FENCE_VIRT -eq 1) AM_CONDITIONAL(BUILD_XENAPILIB, test $XENAPILIB -eq 1) AC_SUBST([IPMITOOL_PATH]) AC_SUBST([OPENSTACK_PATH]) AC_SUBST([AMTTOOL_PATH]) AC_SUBST([COROSYNC_CMAPCTL_PATH]) AC_SUBST([SG_PERSIST_PATH]) AC_SUBST([SG_TURS_PATH]) AC_SUBST([VGS_PATH]) AC_SUBST([POWERMAN_PATH]) ## fence-virt stuff sysconf=$(eval echo $sysconfdir) AC_DEFINE_UNQUOTED([SYSCONFDIR], ["$sysconf"], [Default config dir]) # # Modular build for fence_virtd to split up dependencies # (default) # AC_ARG_ENABLE(modules, [AS_HELP_STRING([--disable-modules], [Disable modular build])], [ modules=$enableval ], [ modules=yes ]) AM_CONDITIONAL([modularbuild], [test "x$modules" == "xyes"]) if test "x$modules" == "xyes"; then AC_DEFINE_UNQUOTED([_MODULE], [1], [modular build]) fi ### The following options only are used when $modules="yes" ### # Null plugin: Disabled by default AC_ARG_ENABLE(null-plugin, [AS_HELP_STRING([--enable-null-plugin], [Enable null (no-op) backend plugin])], [ modnull=$enableval ], [ modnull=no ]) AM_CONDITIONAL([modnull], [test "x$modnull" == "xyes"]) # libvirt plugin: Enabled by default AC_ARG_ENABLE(libvirt-plugin, [AS_HELP_STRING([--disable-libvirt-plugin], [Disable local-mode libvirt backend plugin])], [ modlibvirt=$enableval ], [ modlibvirt=yes ]) AM_CONDITIONAL([modlibvirt], [test "x$modlibvirt" == "xyes"]) if test "x$modlibvirt" == "xyes"; then PKG_CHECK_MODULES([virt], [libvirt]) fi # cpg plugin: Disabled by default AC_ARG_ENABLE(cpg-plugin, [AS_HELP_STRING([--enable-cpg-plugin], [Enable CPG/libvirt backend plugin])], [ modcpg=$enableval ], [ modcpg=no ]) AM_CONDITIONAL([modcpg], [test "x$modcpg" == "xyes"]) if test "x$modcpg" == "xyes"; then PKG_CHECK_MODULES([cpg], [libcpg]) fi # (broken!) libvirt-qmf plugin: Disabled by default AC_ARG_ENABLE(libvirt-qmf-plugin, [AS_HELP_STRING([--enable-libvirt-qmf-plugin], [Enable libvirt-qmf backend plugin])], [ modlibvirtqmf=$enableval ], [ modlibvirtqmf=no ]) AM_CONDITIONAL([modlibvirtqmf], [test "x$modlibvirtqmf" == "xyes"]) if test "x$modlibvirtqmf" == "xyes"; then PKG_CHECK_MODULES([qpid], [qpid]) fi # (broken with pcmk 2.0!) pm-fence plugin: Disabled by default AC_ARG_ENABLE(pm-fence-plugin, [AS_HELP_STRING([--enable-pm-fence-plugin], [Enable pm-fence backend plugin])], [ modpmfence=$enableval ], [ modpmfence=no ]) AM_CONDITIONAL([modpmfence], [test "x$modpmfence" == "xyes"]) if test "x$modpmfence" == "xyes"; then PKG_CHECK_MODULES([cib], [pacemaker-cib]) PKG_CHECK_MODULES([ncurses], [ncurses]) PKG_CHECK_MODULES([glib2], [glib-2.0]) AC_SEARCH_LIBS([read_attr_delegate], [cib], [ ], [ AC_DEFINE_UNQUOTED([PM_1_0], [1], [pacemaker 1.0]) ]) fi # multicast plugin: Enabled by default AC_ARG_ENABLE(multicast-plugin, [AS_HELP_STRING([--disable-multicast-plugin], [Disable multicast listener plugin])], [ modmulticast=$enableval ], [ modmulticast=yes ]) AM_CONDITIONAL([modmulticast], [test "x$modmulticast" == "xyes"]) # tcp plugin: Enabled by default AC_ARG_ENABLE(tcp-plugin, [AS_HELP_STRING([--disable-tcp-plugin], [Disable TCP listener plugin])], [ modtcp=$enableval ], [ modtcp=yes ]) AM_CONDITIONAL([modtcp], [test "x$modtcp" == "xyes"]) # serial/libvirt plugin: Enabled by default AC_ARG_ENABLE(serial-plugin, [AS_HELP_STRING([--disable-serial-plugin], [Disable serial listener plugin])], [ modserial=$enableval ], [ modserial=yes ]) AM_CONDITIONAL([modserial], [test "x$modserial" == "xyes"]) # vsock plugin: Enabled by default AC_ARG_ENABLE(vsock-plugin, [AS_HELP_STRING([--disable-vsock-plugin], [Disable TCP listener plugin])], [ modvsock=$enableval ], [ modvsock=yes ]) AM_CONDITIONAL([modvsock], [test "x$modvsock" == "xyes"]) # # Compatibility symlink: enabled by default # AC_ARG_ENABLE(xvm-compat, [AS_HELP_STRING([--disable-xvm-compat], [Disable fence_xvm symlink compatibility])], [ xvmcompat=$enableval ], [ xvmcompat=yes ]) AM_CONDITIONAL([xvmcompat], [test "x$xvmcompat" == "xyes"]) # Try to detect the appropriate conf dir. Several systems have both /etc/default # and /etc/sysconfig but latter is always primary. AC_ARG_VAR(initconfdir, [directory for initscripts configuration]) if test "x$initconfdir" = x; then AC_CHECK_FILE(/etc/conf.d, [initconfdir='$(sysconfdir)/conf.d}'], [# Gentoo/Arch AC_CHECK_FILE(/etc/sysconfig, [initconfdir='$(sysconfdir)/sysconfig'], [# RedHat/Fedora/Slax/Mandriva/S AC_CHECK_FILE(/etc/default, [initconfdir='$(sysconfdir)/default'], [# Debian/Ubuntu AC_MSG_ERROR([could not determine system initscripts config dir; please set initconfdir manually.])])])]) fi ## *FLAGS handling ENV_CFLAGS="$CFLAGS" ENV_CPPFLAGS="$CPPFLAGS" ENV_LDFLAGS="$LDFLAGS" # debug build stuff if test "x${enable_debug}" = xyes; then AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code]) OPT_CFLAGS="-O0" else OPT_CFLAGS="-O2" fi # gdb flags if test "x${GCC}" = xyes; then GDB_FLAGS="-ggdb3" else GDB_FLAGS="-g" fi # extra warnings EXTRA_WARNINGS="" WARNLIST=" error all shadow missing-prototypes missing-declarations strict-prototypes declaration-after-statement pointer-arith + write-strings " #WARNLIST=" -# write-strings # cast-align # bad-function-cast # missing-format-attribute # format=2 # format-security # format-nonliteral # no-long-long # unsigned-char # gnu89-inline # no-strict-aliasing # " for j in $WARNLIST; do if cc_supports_flag -W$j; then EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j"; fi done CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS \ $EXTRA_WARNINGS $WERROR_CFLAGS" CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS" LDFLAGS="$ENV_LDFLAGS" AM_EXTRA_RECURSIVE_TARGETS([xml-check xml-upload]) AX_PROG_DATE AS_IF([test "$ax_cv_prog_date_gnu_date:$ax_cv_prog_date_gnu_utc" = yes:yes], [UTC_DATE_AT="date -u -d@"], [AS_IF([test "x$ax_cv_prog_date_bsd_date" = xyes], [UTC_DATE_AT="date -u -r"], [AC_MSG_ERROR([date utility unable to convert epoch to UTC])])]) AC_SUBST([UTC_DATE_AT]) AC_ARG_VAR([SOURCE_EPOCH],[last modification date of the source]) AC_MSG_NOTICE([trying to determine source epoch]) AC_MSG_CHECKING([for source epoch in \$SOURCE_EPOCH]) AS_IF([test -n "$SOURCE_EPOCH"], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_CHECKING([for source epoch in source_epoch file]) AS_IF([test -e "$srcdir/source_epoch"], [read SOURCE_EPOCH <"$srcdir/source_epoch" AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_CHECKING([for source epoch baked in by gitattributes export-subst]) SOURCE_EPOCH='$Format:%at$' # template for rewriting by git-archive AS_CASE([$SOURCE_EPOCH], [?Format:*], # was not rewritten [AC_MSG_RESULT([no]) AC_MSG_CHECKING([for source epoch in \$SOURCE_DATE_EPOCH]) AS_IF([test "x$SOURCE_DATE_EPOCH" != x], [SOURCE_EPOCH="$SOURCE_DATE_EPOCH" AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_CHECKING([whether git log can provide a source epoch]) SOURCE_EPOCH=f${SOURCE_EPOCH#\$F} # convert into git log --pretty format SOURCE_EPOCH=$(cd "$srcdir" && git log -1 --pretty=${SOURCE_EPOCH%$} 2>/dev/null) AS_IF([test -n "$SOURCE_EPOCH"], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no, using current time and breaking reproducibility]) SOURCE_EPOCH=$(date +%s)])])], [AC_MSG_RESULT([yes])] )]) ]) AC_MSG_NOTICE([using source epoch $($UTC_DATE_AT$SOURCE_EPOCH +'%F %T %Z')]) if test "x$VERSION" = "xUNKNOWN"; then AC_MSG_ERROR([m4_text_wrap([ configure was unable to determine the source tree's current version. This generally happens when using git archive (or the github download button) generated tarball/zip file. In order to workaround this issue, either use git clone https://github.com/ClusterLabs/fence-virt.git or use an official release tarball. Alternatively you can add a compatible version in a .tarball-version file at the top of the source tree, wipe your autom4te.cache dir and generated configure, and rerun autogen.sh. ], [ ], [ ], [76])]) fi AC_CONFIG_FILES([Makefile fence-agents.pc agents/Makefile lib/Makefile doc/Makefile agents/virt/Makefile agents/virt/config/Makefile agents/virt/common/Makefile agents/virt/client/Makefile agents/virt/server/Makefile agents/virt/man/Makefile ]) AC_OUTPUT