Beispiel #1
0
int main(int argc, char **argv)
{
	vps_param *param, *gparam;
	struct stat st;
	char *infile = NULL;
	int opt, recover = 0, ask = 0;
	int ret = 1;
	int vswap = -1;

	init_log(NULL, 0, 1, 0, 0, progname);

	while ((opt = getopt(argc, argv, "rihv:")) > 0) {
		switch(opt) {
		case 'r'	:
			recover = 1;
			break;
		case 'i'	:
			ask = 1;
			break;
		case 'h'	:
			usage(0);
		case 'v':
			switch (yesno2id(optarg)) {
				case YES:
					vswap = 1;
					break;
				case NO:
					vswap = 0;
					break;
				default:
					logger(-1, 0, "Invalid argument "
							"for -v: %s", optarg);
					usage(1);
			}
			break;
		default	:
			usage(1);
		}
	}
	if (optind >= argc)
		usage(1);

	if ((page_size = get_pagesize()) < 0)
		return 1;

	/* Read global config */
	gparam = init_vps_param();
	if (vps_parse_config(0, GLOBAL_CFG, gparam, NULL)) {
		logger(-1, 0, "WARNING: Global configuration file %s "
			"not found", GLOBAL_CFG);
	}

	/* Read container config */
	infile = strdup(argv[optind]);
	if (!infile) {
		logger(-1, 0, "No free memory");
		goto err;
	}
	if (stat(infile, &st)) {
		logger(-1, 0, "Container configuration file %s not found",
			infile);
		goto err;
	}
	param = init_vps_param();
	if (vps_parse_config(0, infile, param, NULL))
		goto err;

	/* Merge configs (needed for DISK_QUOTA value, maybe others) */
	merge_vps_param(gparam, param);

	if (vswap == -1)
		vswap = is_vswap_config(&param->res.ub);

	if (!(ret = validate(&param->res, recover, ask, vswap))) {
		if (recover || ask)
			if (vps_save_config(0, infile, param, NULL, NULL))
				goto err;
		logger(-1, 0, "Validation completed: success");
		ret = 0;
	}
	else
		ret = 2;

err:
	free(infile);
	exit(ret);
}
Beispiel #2
0
/** Register Container
 * @param path		Container private data root
 * @param param		struct vzctl_reg_param
 * @param flags		registration flags
 * @return		veid or -1 in case error
 */
int vzctl2_env_register(const char *path, struct vzctl_reg_param *param, int flags)
{
	char buf[PATH_MAX];
	char veconf[STR_SIZE];
	char path_r[PATH_MAX];
	struct stat st;
	int ret, err;
	struct vzctl_env_handle *h;
	FILE *fp;
	char ve_host[STR_SIZE];
	char host[STR_SIZE];
	int owner_check_res;
	int on_pcs, on_shared;
	int ha_resource_added = 0;
	int ha_enable = 0;
	const char *data, *name;
	ctid_t ctid = {};
	ctid_t uuid = {};

	/* preserve compatibility
	 * VZ_REG_SKIP_HA_CLUSTER is alias for VZ_REG_SKIP_CLUSTER
	 */
	if (flags & VZ_REG_SKIP_HA_CLUSTER)
		flags |= VZ_REG_SKIP_CLUSTER;

	if (stat(path, &st) != 0)
		return vzctl_err(-1, errno, "Unable to stat %s", path);

	if (realpath(path, path_r) == NULL)
		return vzctl_err(-1, errno, "Failed to get realpath %s", path);

	ret = vzctl2_env_layout_version(path_r);
	if (ret == -1) {
		return -1;
	} else if (ret < VZCTL_LAYOUT_4)
		return vzctl_err(-1, 0, "Warning: Container in old data format,"
				" registration skipped.");

	snprintf(veconf, sizeof(veconf), "%s/" VZCTL_VE_CONF, path_r);
	if (stat(veconf, &st)) {
		logger(-1, 0, "Error: Broken Container, no %s file found", veconf);
		return -1;
	}

	h = vzctl2_env_open_conf(param->ctid, veconf, 0, &err);
	if (h == NULL)
		return -1;

	data = param->uuid;
	/* get UUID from config if not specified */
	if (data == NULL)
		vzctl2_env_get_param(h, "UUID", &data);

	if (get_cid_uuid_pair(param->ctid, data, ctid, uuid))
		goto err;

	owner_check_res = vzctl_check_owner_quiet(
			path_r, host, sizeof(host), ve_host, sizeof(ve_host));
	on_pcs = (is_pcs(path_r) == 1);
	on_shared = (is_shared_fs(path_r) == 1);

        if (vzctl2_env_get_param(h, "HA_ENABLE", &data) == 0 && data != NULL)
                ha_enable = yesno2id(data);

	if (on_pcs && ha_enable != VZCTL_PARAM_OFF &&
			check_external_disk(path_r, h->env_param->disk) &&
			shaman_is_configured())
	{
		logger(-1, 0, "Containers with external disks cannot be"
				" registered in a High Availability cluster");
		goto err;
	}

	if (!(flags & VZ_REG_FORCE)) {
		/* ignore renew option for pstorage (https://jira.sw.ru/browse/PSBM-16819) */
		if (on_pcs)
			flags &= ~VZ_REG_RENEW;

		if (!(flags & VZ_REG_RENEW) && owner_check_res) {
			if (owner_check_res == VZCTL_E_ENV_MANAGE_DISABLED) {
				logger(-1, 0, "Owner check failed on the server %s;"
					" Container is registered for %s", host, ve_host);
				if (on_pcs)
					logger(0, 0,
					"Failed to register the Container/virtual machine. "
					"You can force the registration, but this will revoke "
					"all access to the Container from the original server.");
			}
			goto err;
		}

		if (validate_eid(h, &st, ctid))
			goto err;
	} else if ((owner_check_res == VZCTL_E_ENV_MANAGE_DISABLED) && on_shared) {
		if (on_pcs && !(flags & VZ_REG_SKIP_CLUSTER)) {
			/* [pstorage:] if CT already registered on other node, revoke leases */
			/* before files editing (https://jira.sw.ru/browse/PSBM-16819) */
			char *argv[] = { "/usr/bin/pstorage", "revoke", "-R", (char *)path_r, NULL };
			/* it is irreversible operation */
			if (vzctl2_wrap_exec_script(argv, NULL, 0))
				goto err;
		}
		if (!(flags & VZ_REG_SKIP_CLUSTER) && (ha_enable != VZCTL_PARAM_OFF)) {
			/* remove resource from HA cluster
			 * TODO : execute 'del-everywhere' and 'add' by one command
			 *	 (https://jira.sw.ru/browse/PSBM-17374
			 */
			shaman_del_everywhere(ctid);
		}
	}
	if (!(flags & VZ_REG_SKIP_CLUSTER) && on_shared && (ha_enable != VZCTL_PARAM_OFF)) {
		/* TODO : execute 'del-everywhere' and 'add' by one command
		 *		(https://jira.sw.ru/browse/PSBM-17374)
		 * Right now ask HA cluster to register CT as resource
		 * and will do it before filesystem operations
		 */
		if (shaman_add_resource(ctid, h->conf, path_r)) {
			logger(-1, 0, "Error: Failed to register the Container %s on HA cluster",
					ctid);
			goto err;
		}
		ha_resource_added = 1;
	}

	if (!(flags & VZ_REG_SKIP_OWNER)) {
		snprintf(buf, sizeof(buf), "%s/" VZCTL_VE_OWNER, path_r);
		if ((fp = fopen(buf, "w")) == NULL) {
			logger(-1, errno, "Unable to register the Container; failed to create"
					" the file %s", buf);
			goto err;
		}
		if (get_serverid(buf, sizeof(buf)) == 0)
			fprintf(fp, "%s", buf);
		fclose(fp);
	}

	ret = renew_VE_PRIVATE(h, path, ctid);
	if (ret)
		goto err;

	/* restore CT name */
	name = param->name ?: h->env_param->name->name;
	if (name != NULL && *name != '\0') {
		ctid_t t;
		char x[PATH_MAX];
		const char *new_name = name;
		const char *veid = NULL;

		vzctl2_env_get_param(h, "VEID", &veid);

		if (vzctl2_get_envid_by_name(name, t) == 0 &&
				veid != NULL && CMP_CTID(t, veid))
		{
			logger(-1, 0, "Name %s is in use by CT %s", name, t);
			new_name = gen_uniq_name(name, x, sizeof(x));
		}

		vzctl2_env_set_param(h, "NAME", new_name);
		if (h->env_param->name->name) {
			struct stat st_n;

			snprintf(buf, sizeof(buf), ENV_NAME_DIR "%s",
					h->env_param->name->name);
			if (stat(buf, &st_n) == 0 && st.st_dev == st_n.st_dev)
				unlink(buf);
		}

		logger(0, 0, "Assign the name: %s", new_name);
		snprintf(buf, sizeof(buf), ENV_NAME_DIR "%s", new_name);
		unlink(buf);
		if (symlink(veconf, buf)) {
			logger(-1, errno, "Unable to create the link %s", buf);
			goto err;
		}
	}

	vzctl2_env_set_param(h, "VEID", ctid);
	/* Update UUID */
	vzctl2_env_set_param(h, "UUID", uuid);
	if (flags & (VZ_REG_RENEW_NETIF_IFNAME|VZ_REG_RENEW_NETIF_MAC)) {
		if (h->env_param->veth &&
				!list_empty(&h->env_param->veth->dev_list)) {
			h->env_param->veth->delall = 1;
			data = veth2str(h->env_param, h->env_param->veth, flags);
			if (data != NULL)
				vzctl2_env_set_param(h, "NETIF", data);
		}
	}

	ret = vzctl2_env_save_conf(h, veconf);
	if (ret)
		goto err;

	/* create registration */
	vzctl2_get_env_conf_path(ctid, buf, sizeof(buf));
	unlink(buf);
	if (symlink(veconf, buf)) {
		logger(-1, errno, "Failed to create the symlink %s", buf);
		goto err;
	}

	vzctl2_env_close(h);
	vzctl2_send_state_evt(ctid, VZCTL_ENV_REGISTERED);

	logger(0, 0, "Container %s was successfully registered", ctid);
	return 0;

err:
	if (ha_resource_added)
		shaman_del_resource(ctid);
	vzctl2_env_close(h);
	logger(-1, 0, "Container registration failed: %s",
			vzctl2_get_last_error());

	return -1;
}