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(¶m->res.ub); if (!(ret = validate(¶m->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); }
/** 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; }