Пример #1
0
static int
backend_config_checkpoint(config_object_t *config)
{
	char val[4096];
	char inp[4096];
	int done = 0;

	printf("\n");
	printf("The checkpoint backend module is designed for use in clusters\n"
	       "running corosync, openais, and CMAN.  It utilizes the SAF \n"
	       "checkpoint API to store virtual machine states and CPG to \n"
	       "route fencing requests, finally utilizing libvirt to perform\n"
	       "fencing actions.\n\n");

	if (sc_get(config, "backends/checkpoint/@uri", val,
		   sizeof(val))) {
		strncpy(val, DEFAULT_HYPERVISOR_URI, sizeof(val));
	}

	text_input("Libvirt URI", val, inp, sizeof(inp));

	sc_set(config, "backends/checkpoint/@uri", inp);

	printf("\n");
	printf("The name mode is how the checkpoint plugin stores and \n"
	       "references virtual machines.  Since virtual machine names\n"
	       "are not guaranteed to be unique cluster-wide, use of UUIDs\n"
	       "is strongly recommended.  However, for compatibility with \n"
	       "fence_xvmd, the use of 'name' mode is also supported.\n\n");

	if (sc_get(config, "backends/checkpoint/@name_mode", val,
		   sizeof(val))) {
		strncpy(val, "uuid", sizeof(val));
	}

	do {
		text_input("VM naming/tracking mode (name or uuid)",
			   val, inp, sizeof(inp));
		if (!strcasecmp(inp, "uuid")) {
			done = 1;
		} else if (!strcasecmp(inp, "name")) {
			done = 0;
			printf("This can be dangerous if you do not take care to"
			       "ensure that\n"
			       "virtual machine names are unique "
			       "cluster-wide.\n");
			if (yesno("Use name mode anyway", 1) == 1)
				done = 1;
		}
	} while (!done);

	sc_set(config, "backends/checkpoint/@name_mode", inp);

	return 0;
}
Пример #2
0
static int
libvirt_init(backend_context_t *c, config_object_t *config)
{
	virConnectPtr vp;
	char value[256];
	struct libvirt_info *info = NULL;
	char *uri = NULL;

	info = malloc(sizeof(*info));
	if (!info)
		return -1;

	dbg_printf(5, "[%s:%d %s]\n", __FILE__, __LINE__, __FUNCTION__);
	memset(info, 0, sizeof(*info));

#ifdef _MODULE
	if (sc_get(config, "fence_virtd/@debug", value, sizeof(value))==0)
		dset(atoi(value));
#endif

	if (sc_get(config, "backends/libvirt/@uri",
		   value, sizeof(value)) == 0) {
		uri = strdup(value);
		if (!uri) {
			free(info);
			return -1;
		}
		dbg_printf(1, "Using %s\n", uri);
	}

	/* We don't need to store the URI; we only use it once */
	vp = virConnectOpen(uri);
	if (!vp) {
		free(uri);
		free(info);
		return -1;
	}
	free(uri);

	info->magic = MAGIC;
	info->vp = vp;

	*c = (void *)info;
	return 0;
}
Пример #3
0
static void
cpg_virt_init_libvirt(struct cpg_info *info) {
	config_object_t *config = info->config;
	int i = 0;

	if (info->vp) {
		dbg_printf(2, "Lost libvirtd connection. Reinitializing.\n");
		for (i = 0 ; i < info->vp_count ; i++)
			virConnectClose(info->vp[i]);
		free(info->vp);
		info->vp = NULL;
	}
	info->vp_count = 0;

	do {
		virConnectPtr vp;
		virConnectPtr *vpl = NULL;
		char conf_attr[256];
		char value[1024];
		char *uri;

		if (i != 0) {
			snprintf(conf_attr, sizeof(conf_attr),
				"backends/cpg/@uri%d", i);
		} else
			snprintf(conf_attr, sizeof(conf_attr), "backends/cpg/@uri");
		++i;

		if (sc_get(config, conf_attr, value, sizeof(value)) != 0)
			break;

		uri = value;
		vp = virConnectOpen(uri);
		if (!vp) {
			dbg_printf(1, "[cpg-virt:INIT] Failed to connect to URI: %s\n", uri);
			continue;
		}

		vpl = realloc(info->vp, sizeof(*info->vp) * (info->vp_count + 1));
		if (!vpl) {
			dbg_printf(1, "[cpg-virt:INIT] Out of memory allocating URI: %s\n",
				uri);
			virConnectClose(vp);
			continue;
		}

		info->vp = vpl;
		info->vp[info->vp_count++] = vp;

		if (i > 1)
			dbg_printf(1, "[cpg-virt:INIT] Added URI%d %s\n", i - 1, uri);
		else
			dbg_printf(1, "[cpg_virt:INIT] Added URI %s\n", uri);
	} while (1);
}
Пример #4
0
static void
eat_buffer(void)
{
	D("eating buffer");
	int seenempty = 0;
	bool fresh = true;
	for(;;) {
		fd_set fds;
		FD_ZERO(&fds);
		FD_SET(s_fd,&fds);
		struct timeval to;
		to.tv_sec = 0;
		to.tv_usec = 0;

		int r = select(s_fd+1, &fds, 0, 0, &to);
		if (r == 0) {
			if (fresh) {
				D("buffer apparently empty");
				break;
			}
			fresh = false;

			if (!seenempty) {
				usleep(999999);
				seenempty = 1;
				continue;
			} else {
				D("buffer apparently empty");
				break;
			}
		} else if (r == -1) {
			CE("select failed");
		} else {
			fresh = false;
			if (FD_ISSET(s_fd, &fds)) {
				seenempty = 0;
				D("discarded a byte");
				sc_get(); //discard
			} else
				C("wat?");
		}
	}
}
Пример #5
0
static int
listener_configure(config_object_t *config)
{
    char val[4096];
    char inp[4096];
    int done = 0;

    printf("\n");
    printf("Listener modules are responsible for accepting requests\n"
           "from fencing clients.\n\n");

    /* Default backend plugin */
    if (sc_get(config, "fence_virtd/@listener", val,
               sizeof(val))) {
        strncpy(val, "multicast", sizeof(val));
    }

    do {
        text_input("Listener module", val, inp, sizeof(inp));
        if (plugin_find_listener(inp) == NULL) {
            printf("No listener module named %s found!\n", inp);
            if (yesno("Use this value anyway", 0) == 1)
                done = 1;
        } else {
            done = 1;
        }
    } while (!done);

    sc_set(config, "fence_virtd/@listener", inp);
    if (!strcmp(inp, "multicast"))
        listener_config_multicast(config);
    else if (!strcmp(inp, "tcp"))
        listener_config_tcp(config);
    else if (!strcmp(inp, "serial"))
        listener_config_serial(config);
    else
        printf("I don't know how to configure '%s' :(\n",
               inp);

    return 0;
}
Пример #6
0
static int
backend_configure(config_object_t *config)
{
    char val[4096];
    char inp[4096];
    int done = 0;

    printf("\n");
    printf("Backend modules are responsible for routing requests to\n"
           "the appropriate hypervisor or management layer.\n\n");

    /* Default backend plugin */
    if (sc_get(config, "fence_virtd/@backend", val,
               sizeof(val))) {
        strncpy(val, "libvirt", sizeof(val));
    }

    do {
        text_input("Backend module", val, inp, sizeof(inp));
        if (plugin_find_backend(inp) == NULL) {
            printf("No backend module named %s found!\n", inp);
            if (yesno("Use this value anyway", 0) == 1)
                done = 1;
        } else {
            done = 1;
        }
    } while (!done);

    sc_set(config, "fence_virtd/@backend", inp);

#if 0
    if (!strcmp(inp, "libvirt")) {
        backend_config_libvirt(config);
    } else if (!strcmp(inp, "checkpoint")) {
        backend_config_checkpoint(config);
    }
#endif

    return 0;
}
Пример #7
0
static int
plugin_path_configure(config_object_t *config)
{
#ifdef _MODULE
	char val[4096];
	char inp[4096];
	int done = 0;

	if (sc_get(config, "fence_virtd/@module_path", val,
	   	   sizeof(val))) {
#ifdef MODULE_PATH
		snprintf(val, sizeof(val), MODULE_PATH);
#else
		printf("Failed to determine module search path.\n");
#endif
	}

	do {
		text_input("Module search path", val, inp, sizeof(inp));

		printf("\n");
		done = plugin_search(inp);
		if (done > 0) {
			plugin_dump();
			done = 1;
		} else {
			done = 0;
			printf("No modules found in %s!\n", inp);
			if (yesno("Use this value anyway", 0) == 1)
				done = 1;
		}
	} while (!done);

	sc_set(config, "fence_virtd/@module_path", inp);

#endif
	return 0;
}
Пример #8
0
static int
backend_config_libvirt(config_object_t *config)
{
	char val[4096];
	char inp[4096];

	printf("\n");
	printf("The libvirt backend module is designed for single desktops or\n"
	       "servers.  Do not use in environments where virtual machines\n"
	       "may be migrated between hosts.\n\n");

	/* Default backend plugin */
	if (sc_get(config, "backends/libvirt/@uri", val,
		   sizeof(val))) {
		strncpy(val, DEFAULT_HYPERVISOR_URI, sizeof(val));
	}

	text_input("Libvirt URI", val, inp, sizeof(inp));

	sc_set(config, "backends/libvirt/@uri", inp);

	return 0;
}
Пример #9
0
static int
listener_config_serial(config_object_t *config)
{
	char val[4096];
	char inp[4096];

	printf("\n");
	printf("The serial plugin allows fence_virtd to communicate with\n"
	       "guests using serial or guest-forwarding VMChannel instead\n"
	       "of using TCP/IP networking.\n\n");
	printf("Special configuration of virtual machines is required. See\n"
	       "fence_virt.conf(5) for more details.\n\n");

	if (sc_get(config, "listeners/serial/@uri",
		   val, sizeof(val)-1)) {
		strncpy(val, DEFAULT_HYPERVISOR_URI, sizeof(val));
	}

	text_input("Libvirt URI", val, inp, sizeof(inp));
	
	printf("\nSetting a socket path prevents fence_virtd from taking\n"
	       "hold of all Unix domain sockets created when the guest\n"
	       "is started.  A value like /var/run/cluster/fence might\n"
	       "be a good value.  Don't forget to create the directory!\n\n");

	if (sc_get(config, "listeners/serial/@path",
		   val, sizeof(val)-1)) {
		strncpy(val, "none", sizeof(val));
	}

	text_input("Socket directory", val, inp, sizeof(inp));
	if (!strcasecmp(inp, "none")) {
		sc_set(config, "listeners/serial/@path", NULL);
	} else {
		sc_set(config, "listeners/serial/@path", inp);
	}

	printf("\nThe serial plugin allows two types of guest to host\n"
	       "configurations.  One is via a serial port; the other is\n"
	       "utilizing the newer VMChannel.\n\n");

	if (sc_get(config, "listeners/serial/@mode",
		   val, sizeof(val)-1)) {
		strncpy(val, "serial", sizeof(val));
	}

	if (!strcasecmp(inp, "none")) {
		sc_set(config, "listeners/serial/@path", NULL);
	} else {
		sc_set(config, "listeners/serial/@path", inp);
	}

	do { 
		text_input("Mode (serial or vmchannel)", val, inp,
			   sizeof(inp));

		if (strcasecmp(inp, "serial") &&
		    strcasecmp(inp, "vmchannel")) {
			printf("Invalid mode: %s\n", inp);
			if (yesno("Use anyway", 1) == 1)
				break;
			continue;
		}
	} while(0);
	sc_set(config, "listeners/serial/@mode", inp);

	return 0;
}
Пример #10
0
static int
listener_config_multicast(config_object_t *config)
{
	char val[4096];
	char inp[4096];
	const char *family;
	struct in_addr sin;
	struct in6_addr sin6;
	int done = 0;

	printf("\n");
	printf("The multicast listener module is designed for use environments\n"
	       "where the guests and hosts may communicate over a network using\n"
	       "multicast.\n\n");


	/* MULTICAST IP ADDRESS/FAMILY */
	printf("The multicast address is the address that a client will use to\n"
	       "send fencing requests to fence_virtd.\n\n");

	if (sc_get(config, "listeners/multicast/@address",
		   val, sizeof(val)-1)) {
		strncpy(val, IPV4_MCAST_DEFAULT, sizeof(val));
	}

	do {
		text_input("Multicast IP Address", val, inp, sizeof(inp));

		if (inet_pton(AF_INET, inp, &sin) == 1) {
			printf("\nUsing ipv4 as family.\n\n");
			family = "ipv4";
		} else if (inet_pton(AF_INET6, inp, &sin6) == 1) {
			printf("\nUsing ipv6 as family.\n\n");
			family = "ipv6";
		} else {
			printf("'%s' is not a valid IP address!\n", inp);
			continue;
		}

	} while (0);
	sc_set(config, "listeners/multicast/@family", family);
	sc_set(config, "listeners/multicast/@address", inp);


	/* MULTICAST IP PORT */
	if (sc_get(config, "listeners/multicast/@port",
		   val, sizeof(val)-1)) {
		snprintf(val, sizeof(val), "%d", DEFAULT_MCAST_PORT);
	}

	do {
		text_input("Multicast IP Port", val, inp, sizeof(inp));

		done = atoi(inp);
		if (done <= 0 || done > 65534) {
			printf("Port value '%s' is out of range\n", val);
			continue;
		}

	} while (0);
	sc_set(config, "listeners/multicast/@port", inp);


	/* MULTICAST INTERFACE */
	printf("\nSetting a preferred interface causes fence_virtd to listen only\n"
	       "on that interface.  Normally, it listens on all interfaces.\n"
	       "In environments where the virtual machines are using the host\n"
	       "machine as a gateway, this *must* be set (typically to virbr0).\n"
	       "Set to 'none' for no interface.\n\n"
	      );

	if (sc_get(config, "listeners/multicast/@interface",
		   val, sizeof(val)-1)) {
		strncpy(val, "none", sizeof(val));
	}

	do { 
		text_input("Interface", val, inp, sizeof(inp));

		if (!strcasecmp(inp, "none")) {
			break;
		}

		if (strlen(inp) > 0) {
			done = if_nametoindex(inp);
			if (done < 0) {
				printf("Invalid interface: %s\n", inp);
				if (yesno("Use anyway", 1) == 1)
					break;
				continue;
			}
			break;
		}
	} while(0);

	if (!strcasecmp(inp, "none")) {
		sc_set(config, "listeners/multicast/@interface", NULL);
	} else {
		sc_set(config, "listeners/multicast/@interface", inp);
	}


	/* KEY FILE */
	printf("\nThe key file is the shared key information which is used to\n"
	       "authenticate fencing requests.  The contents of this file must\n"
	       "be distributed to each physical host and virtual machine within\n"
	       "a cluster.\n\n");

	if (sc_get(config, "listeners/multicast/@key_file",
		   val, sizeof(val)-1)) {
		strncpy(val, DEFAULT_KEY_FILE, sizeof(val));
	}

	do { 
		text_input("Key File", val, inp, sizeof(inp));

		if (!strcasecmp(inp, "none")) {
			break;
		}

		if (strlen(inp) > 0) {
			if (inp[0] != '/') {
				printf("Invalid key file: %s\n", inp);
				if (yesno("Use anyway", 1) == 1)
					break;
				continue;
			}
			break;
		}
	} while(0);
	if (!strcasecmp(inp, "none")) {
		sc_set(config, "listeners/multicast/@key_file", NULL);
	} else {
		sc_set(config, "listeners/multicast/@key_file", inp);
	}

	return 0;
}
Пример #11
0
int
main(int argc, char **argv)
{
	char val[4096];
	char listener_name[80];
	char backend_name[80];
	const char *config_file = DEFAULT_CONFIG_FILE;
	config_object_t *config = NULL;
	map_object_t *map = NULL;
	const listener_plugin_t *lp;
	const backend_plugin_t *p;
	listener_context_t listener_ctx = NULL;
	backend_context_t backend_ctx = NULL;
	int debug_set = 0, foreground = 0, wait_for_init = 0;
	int opt, configure = 0;

	config = sc_init();
	map = map_init();

	if (!config || !map) {
		perror("malloc");
		return -1;
	}

	while ((opt = getopt(argc, argv, "Ff:d:cwlh")) != EOF) {
		switch(opt) {
		case 'F':
			printf("Background mode disabled\n");
			foreground = 1;
			break;
		case 'f':
			printf("Using %s\n", optarg);
			config_file = optarg;
			break;
		case 'd':
			debug_set = atoi(optarg);
			break;
		case 'c':
			configure = 1;
			break;
		case 'w':
			wait_for_init = 1;
			break;
		case 'l':
			plugin_dump();
			return 0;
		case 'h':
		case '?':
			usage();
			return 0;
		default:
			return -1;
		}
	}

	if (configure) {
		return do_configure(config, config_file);
	}

	if (sc_parse(config, config_file) != 0) {
		printf("Failed to parse %s\n", config_file);
		return -1;
	}

	if (debug_set) {
		snprintf(val, sizeof(val), "%d", debug_set);
		sc_set(config, "fence_virtd/@debug", val);
	} else {
		if (sc_get(config, "fence_virtd/@debug", val, sizeof(val))==0)
			debug_set = atoi(val);
	}

	dset(debug_set);

	if (!foreground) {
		if (sc_get(config, "fence_virtd/@foreground",
			   val, sizeof(val)) == 0)
			foreground = atoi(val);
	}

	if (!wait_for_init) {
		if (sc_get(config, "fence_virtd/@wait_for_init",
			   val, sizeof(val)) == 0)
			wait_for_init = atoi(val);
		if (!wait_for_init) {
			/* XXX compat */
			if (sc_get(config, "fence_virtd/@wait_for_backend",
				   val, sizeof(val)) == 0)
				wait_for_init = atoi(val);
		}
	}

	if (dget() > 3)
		sc_dump(config, stdout);

	if (sc_get(config, "fence_virtd/@backend", backend_name,
		   sizeof(backend_name))) {
		printf("Failed to determine backend.\n");
		printf("%s\n", val);
		return -1;
	}

	dbg_printf(1, "Backend plugin: %s\n", backend_name);

	if (sc_get(config, "fence_virtd/@listener", listener_name,
		   sizeof(listener_name))) {
		printf("Failed to determine backend.\n");
		printf("%s\n", val);
		return -1;
	}

	dbg_printf(1, "Listener plugin: %s\n", listener_name);

#ifdef _MODULE
	if (sc_get(config, "fence_virtd/@module_path", val,
		   sizeof(val))) {
#ifdef MODULE_PATH
		snprintf(val, sizeof(val), MODULE_PATH);
#else
		printf("Failed to determine module path.\n");
		return -1;
#endif
	}

	dbg_printf(1, "Searching %s for plugins...\n", val);

	opt = plugin_search(val);
	if (opt > 0) {
		dbg_printf(1, "%d plugins found\n", opt);
	} else {
		printf("No plugins found\n");
		return 1;
	}

#endif
	if (dget() > 3)
		plugin_dump();

	lp = plugin_find_listener(listener_name);
	if (!lp) {
		printf("Could not find listener \"%s\"\n", listener_name);
		return 1;
	}

	p = plugin_find_backend(backend_name);
	if (!p) {
		printf("Could not find backend \"%s\"\n", backend_name);
		return 1;
	}

	daemon_init(basename(argv[0]), foreground);
	signal(SIGINT, exit_handler);
	signal(SIGTERM, exit_handler);
	signal(SIGQUIT, exit_handler);

	syslog(LOG_NOTICE, "fence_virtd starting.  Listener: %s  Backend: %s", backend_name, listener_name);

	while (p->init(&backend_ctx, config) < 0) {
		if (!wait_for_init) {
			if (foreground) {
				printf("Backend plugin %s failed to initialize\n",
				       backend_name);
			}
			syslog(LOG_ERR,
			       "Backend plugin %s failed to initialize\n",
			       backend_name);
			return 1;
		}
		sleep(5);
	}

	if (map_load(map, config) < 0) {
		syslog(LOG_WARNING, "Failed to load static maps\n");
	}

	/* only client we have now is mcast (fence_xvm behavior) */
	while (lp->init(&listener_ctx, p->callbacks, config, map,
			backend_ctx) != 0) {
		if (!wait_for_init) {
			if (foreground) {
				printf("Listener plugin %s failed to initialize\n",
				       listener_name);
			}
			syslog(LOG_ERR,
			       "Listener plugin %s failed to initialize\n",
			       listener_name);
			return 1;
		}
		sleep(5);
	}

	while (run && lp->dispatch(listener_ctx, NULL) >= 0);

	syslog(LOG_NOTICE, "fence_virtd shutting down");

	map_release(map);
	sc_release(config);

	lp->cleanup(listener_ctx);
	p->cleanup(backend_ctx);

	daemon_cleanup();

	return 0;
}
Пример #12
0
static int
mcast_config(config_object_t *config, mcast_options *args)
{
	char value[1024];
	int errors = 0;

#ifdef _MODULE
	if (sc_get(config, "fence_virtd/@debug", value, sizeof(value))==0)
		dset(atoi(value));
#endif

	if (sc_get(config, "listeners/multicast/@key_file",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for key_file\n", value);
		args->key_file = strdup(value);
	} else {
		args->key_file = strdup(DEFAULT_KEY_FILE);
		if (!args->key_file) {
			dbg_printf(1, "Failed to allocate memory\n");
			return -1;
		}
	}

	args->hash = DEFAULT_HASH;
	if (sc_get(config, "listeners/multicast/@hash",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for hash\n", value);
		if (!strcasecmp(value, "none")) {
			args->hash = HASH_NONE;
		} else if (!strcasecmp(value, "sha1")) {
			args->hash = HASH_SHA1;
		} else if (!strcasecmp(value, "sha256")) {
			args->hash = HASH_SHA256;
		} else if (!strcasecmp(value, "sha512")) {
			args->hash = HASH_SHA512;
		} else {
			dbg_printf(1, "Unsupported hash: %s\n", value);
			++errors;
		}
	}
	
	args->auth = DEFAULT_AUTH;
	if (sc_get(config, "listeners/multicast/@auth",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for auth\n", value);
		if (!strcasecmp(value, "none")) {
			args->auth = AUTH_NONE;
		} else if (!strcasecmp(value, "sha1")) {
			args->auth = AUTH_SHA1;
		} else if (!strcasecmp(value, "sha256")) {
			args->auth = AUTH_SHA256;
		} else if (!strcasecmp(value, "sha512")) {
			args->auth = AUTH_SHA512;
		} else {
			dbg_printf(1, "Unsupported auth: %s\n", value);
			++errors;
		}
	}
	
	args->family = PF_INET;
	if (sc_get(config, "listeners/multicast/@family",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for family\n", value);
		if (!strcasecmp(value, "ipv4")) {
			args->family = PF_INET;
		} else if (!strcasecmp(value, "ipv6")) {
			args->family = PF_INET6;
		} else {
			dbg_printf(1, "Unsupported family: %s\n", value);
			++errors;
		}
	}

	if (sc_get(config, "listeners/multicast/@address",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for address\n", value);
		args->addr = strdup(value);
	} else {
		if (args->family == PF_INET) {
			args->addr = strdup(IPV4_MCAST_DEFAULT);
		} else {
			args->addr = strdup(IPV6_MCAST_DEFAULT);
		}
	}
	if (!args->addr) {
		return -1;
	}

	args->port = DEFAULT_MCAST_PORT;
	if (sc_get(config, "listeners/multicast/@port",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for port\n", value);
		args->port = atoi(value);
		if (args->port <= 0) {
			dbg_printf(1, "Invalid port: %s\n", value);
			++errors;
		}
	}

	args->ifindex = 0;
	if (sc_get(config, "listeners/multicast/@interface",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for interface\n", value);
		args->ifindex = if_nametoindex(value);
		if (args->ifindex < 0) {
			dbg_printf(1, "Invalid interface: %s\n", value);
			++errors;
		}
	}

	return errors;
}
Пример #13
0
static int
cpg_virt_init(backend_context_t *c, config_object_t *config)
{
	char value[1024];
	struct cpg_info *info = NULL;
	int ret;

	ret = cpg_start(PACKAGE_NAME,
		do_real_work, store_cb, cpg_join_cb, cpg_leave_cb);
	if (ret < 0)
		return -1;

	info = calloc(1, sizeof(*info));
	if (!info)
		return -1;
	info->magic = MAGIC;
	info->config = config;

#ifdef _MODULE
	if (sc_get(config, "fence_virtd/@debug", value, sizeof(value)) == 0)
		dset(atoi(value));
#endif

	cpg_virt_init_libvirt(info);

	/* Naming scheme is no longer a top-level config option.
	 * However, we retain it here for configuration compatibility with
	 * versions 0.1.3 and previous.
	 */
	if (sc_get(config, "fence_virtd/@name_mode",
		   value, sizeof(value)-1) == 0) {

		dbg_printf(1, "Got %s for name_mode\n", value);
		if (!strcasecmp(value, "uuid")) {
			use_uuid = 1;
		} else if (!strcasecmp(value, "name")) {
			use_uuid = 0;
		} else {
			dbg_printf(1, "Unsupported name_mode: %s\n", value);
		}
	}

	if (sc_get(config, "backends/cpg/@name_mode",
		   value, sizeof(value)-1) == 0)
	{
		dbg_printf(1, "Got %s for name_mode\n", value);
		if (!strcasecmp(value, "uuid")) {
			use_uuid = 1;
		} else if (!strcasecmp(value, "name")) {
			use_uuid = 0;
		} else {
			dbg_printf(1, "Unsupported name_mode: %s\n", value);
		}
	}

	if (info->vp_count < 1) {
		dbg_printf(1, "[cpg_virt:INIT] Could not connect to any hypervisors\n");
		cpg_stop();
		free(info);
		return -1;
	}

	pthread_mutex_lock(&local_vm_list_lock);
	update_local_vms(info);
	pthread_mutex_unlock(&local_vm_list_lock);

	*c = (void *) info;
	cpg_virt_handle = info;
	return 0;
}
Пример #14
0
static int
listener_config_tcp(config_object_t *config)
{
	char val[4096];
	char inp[4096];
	const char *family = "ipv4";
	struct in_addr sin;
	struct in6_addr sin6;
	int done = 0;

	printf("\n");
	printf("The TCP listener module is designed for use in environments\n"
	       "where the guests and hosts communicate over viosproxy.\n\n");

	/* IP ADDRESS/FAMILY */
	printf("The IP address is the address that a client will use to\n"
	       "send fencing requests to fence_virtd.\n\n");

	if (sc_get(config, "listeners/tcp/@address",
		   val, sizeof(val)-1)) {
		strncpy(val, IPV4_MCAST_DEFAULT, sizeof(val));
	}

	done = 0;
	do {
		text_input("TCP Listen IP Address", val, inp, sizeof(inp));

		if (inet_pton(AF_INET, inp, &sin) == 1) {
			printf("\nUsing ipv4 as family.\n\n");
			family = "ipv4";
			done = 1;
		} else if (inet_pton(AF_INET6, inp, &sin6) == 1) {
			printf("\nUsing ipv6 as family.\n\n");
			family = "ipv6";
			done = 1;
		} else {
			printf("'%s' is not a valid IP address!\n", inp);
			continue;
		}
	} while (!done);

	sc_set(config, "listeners/tcp/@family", family);
	sc_set(config, "listeners/tcp/@address", inp);

	/* MULTICAST IP PORT */
	if (sc_get(config, "listeners/tcp/@port",
		   val, sizeof(val)-1)) {
		snprintf(val, sizeof(val), "%d", DEFAULT_MCAST_PORT);
	}

	done = 0;
	do {
		text_input("TCP Listen Port", val, inp, sizeof(inp));
		char *p;
		int ret;

		ret = strtol(inp, &p, 0);
		if (*p != '\0' || ret <= 0 || ret >= 65536) {
			printf("Port value '%s' is out of range\n", val);
			continue;
		}
		done = 1;
	} while (!done);
	sc_set(config, "listeners/tcp/@port", inp);

	/* KEY FILE */
	printf("\nThe key file is the shared key information which is used to\n"
	       "authenticate fencing requests.  The contents of this file must\n"
	       "be distributed to each physical host and virtual machine within\n"
	       "a cluster.\n\n");

	if (sc_get(config, "listeners/tcp/@key_file",
		   val, sizeof(val)-1)) {
		strncpy(val, DEFAULT_KEY_FILE, sizeof(val));
	}

	done = 0;
	do { 
		text_input("Key File", val, inp, sizeof(inp));

		if (!strcasecmp(inp, "none")) {
			break;
		}

		if (strlen(inp) > 0) {
			if (inp[0] != '/') {
				printf("Invalid key file: %s\n", inp);
				if (yesno("Use anyway", 1) == 1)
					done = 1;
			} else
				done = 1;
		} else
			printf("No key file given\n");
	} while (!done);

	if (!strcasecmp(inp, "none")) {
		sc_set(config, "listeners/tcp/@key_file", NULL);
	} else {
		sc_set(config, "listeners/tcp/@key_file", inp);
	}

	return 0;
}
Пример #15
0
static int
vsock_config(config_object_t *config, vsock_options *args)
{
	char value[1024];
	int errors = 0;

#ifdef _MODULE
	if (sc_get(config, "fence_virtd/@debug", value, sizeof(value))==0)
		dset(atoi(value));
#endif

	if (sc_get(config, "listeners/vsock/@key_file",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for key_file\n", value);
		args->key_file = strdup(value);
	} else {
		args->key_file = strdup(DEFAULT_KEY_FILE);
		if (!args->key_file) {
			dbg_printf(1, "Failed to allocate memory\n");
			return -1;
		}
	}

	args->hash = DEFAULT_HASH;
	if (sc_get(config, "listeners/vsock/@hash",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for hash\n", value);
		if (!strcasecmp(value, "none")) {
			args->hash = HASH_NONE;
		} else if (!strcasecmp(value, "sha1")) {
			args->hash = HASH_SHA1;
		} else if (!strcasecmp(value, "sha256")) {
			args->hash = HASH_SHA256;
		} else if (!strcasecmp(value, "sha512")) {
			args->hash = HASH_SHA512;
		} else {
			dbg_printf(1, "Unsupported hash: %s\n", value);
			++errors;
		}
	}
	
	args->auth = DEFAULT_AUTH;
	if (sc_get(config, "listeners/vsock/@auth",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for auth\n", value);
		if (!strcasecmp(value, "none")) {
			args->hash = AUTH_NONE;
		} else if (!strcasecmp(value, "sha1")) {
			args->hash = AUTH_SHA1;
		} else if (!strcasecmp(value, "sha256")) {
			args->hash = AUTH_SHA256;
		} else if (!strcasecmp(value, "sha512")) {
			args->hash = AUTH_SHA512;
		} else {
			dbg_printf(1, "Unsupported auth: %s\n", value);
			++errors;
		}
	}
	
	args->port = DEFAULT_MCAST_PORT;
	if (sc_get(config, "listeners/vsock/@port",
		   value, sizeof(value)-1) == 0) {
		dbg_printf(1, "Got %s for port\n", value);
		args->port = atoi(value);
		if (args->port <= 0) {
			dbg_printf(1, "Invalid port: %s\n", value);
			++errors;
		}
	}

	return errors;
}
Пример #16
0
static int
libvirt_init(backend_context_t *c, config_object_t *config)
{
	virConnectPtr vp;
	char value[256];
	struct libvirt_info *info = NULL;
	int i = 0;

	info = malloc(sizeof(*info));
	if (!info)
		return -1;

	dbg_printf(5, "ENTER [%s:%d %s]\n", __FILE__, __LINE__, __FUNCTION__);
	memset(info, 0, sizeof(*info));

#ifdef _MODULE
	if (sc_get(config, "fence_virtd/@debug", value, sizeof(value)) == 0)
		dset(atoi(value));
#endif

	do {
		virConnectPtr *vpl = NULL;
		char conf_attr[256];
		char *uri;

		if (i != 0) {
			snprintf(conf_attr, sizeof(conf_attr),
				"backends/libvirt/@uri%d", i);
		} else
			snprintf(conf_attr, sizeof(conf_attr), "backends/libvirt/@uri");
		++i;

		if (sc_get(config, conf_attr, value, sizeof(value)) != 0)
			break;

		uri = value;
		vp = virConnectOpen(uri);
		if (!vp) {
			dbg_printf(1, "[libvirt:INIT] Failed to connect to URI: %s\n", uri);
			continue;
		}

		vpl = realloc(info->vp, sizeof(*info->vp) * (info->vp_count + 1));
		if (!vpl) {
			dbg_printf(1, "[libvirt:INIT] Out of memory allocating URI: %s\n",
				uri);
			virConnectClose(vp);
			continue;
		}

		info->vp = vpl;
		info->vp[info->vp_count++] = vp;

		if (i > 1)
			dbg_printf(1, "[libvirt:INIT] Added URI%d %s\n", i - 1, uri);
		else
			dbg_printf(1, "[libvirt:INIT] Added URI %s\n", uri);
	} while (1);

	if (info->vp_count < 1) {
		dbg_printf(1, "[libvirt:INIT] Could not connect to any hypervisors\n");
		if (info->vp)
			free(info->vp);
		free(info);
		return -1;
	}

	info->magic = MAGIC;

	*c = (void *)info;
	return 0;
}
Пример #17
0
static int
lq_init(backend_context_t *c, config_object_t *config)
{
	char value[256];
	struct lq_info *info = NULL;

	info = (lq_info *)malloc(sizeof(*info));
	if (!info)
		return -1;

	memset(info, 0, sizeof(*info));
	info->port = 5672; /* Actually match default qpid port */

	if(sc_get(config, "backends/libvirt-qmf/@host",
		   value, sizeof(value))==0){
		printf("\n\nHOST = %s\n\n",value);	
		info->host = strdup(value);
		if (!info->host) {
			goto out_fail;
		}
	} else {
		info->host = strdup("127.0.0.1");
	}

	if(sc_get(config, "backends/libvirt-qmf/@port",
		   value, sizeof(value)-1)==0){
		printf("\n\nPORT = %d\n\n",atoi(value));	
		info->port = atoi(value);
	}

	if(sc_get(config, "backends/libvirt-qmf/@username",
		   value, sizeof(value))==0){
		printf("\n\nUSERNAME = %s\n\n",value);	
		info->username = strdup(value);
		if (!info->username) {
			goto out_fail;
		}
	}

	if(sc_get(config, "backends/libvirt-qmf/@service",
		   value, sizeof(value))==0){
		printf("\n\nSERVICE = %s\n\n",value);	
		info->service = strdup(value);
		if (!info->service) {
			goto out_fail;
		}
	}

	if(sc_get(config, "backends/libvirt-qmf/@gssapi",
		   value, sizeof(value)-1)==0){
		printf("\n\nGSSAPI = %d\n\n",atoi(value));	
		if (atoi(value) > 0) {
			info->use_gssapi = 1;
		}
	}

	info->magic = MAGIC;

	*c = (void *)info;
	return 0;

out_fail:
	free(info->service);
	free(info->username);
	free(info->host);

	free(info);

	return -1;
}