int vzctl2_env_layout_version(const char *path) { char buf[STR_SIZE]; char ver[16]; int id; struct stat st; if (path == NULL) return 0; snprintf(buf, sizeof(buf), "%s/" VZCTL_VE_LAYOUT, path); if (lstat(buf, &st) == -1) { if (errno != ENOENT) return vzctl_err(-1, errno, "Unable to get the" " Container layout: failed to stat %s", buf); if (stat(path, &st) && errno != ENOENT) return vzctl_err(-1, errno, "Unable to stat %s", path); return 0; } if (!S_ISLNK(st.st_mode)) return 0; id = readlink(buf, ver, sizeof(ver)); if (id < 0 || id >= sizeof(ver)) return vzctl_err(-1, errno, "Error reading Ct layout version from %s", buf); ver[id] = 0; if (sscanf(ver, "%d", &id) != 1) return vzctl_err(-1, 0, "Unknown VZFS version (%s)", ver); return id; }
static int check_link(const char *file, int fd) { struct stat st; if (fstat(fd, &st) < 0) return vzctl_err(-1, errno, "Unable to stat %s", file); if (!S_ISREG(st.st_mode)) return vzctl_err(-1, 0, "password database %s is not regular file", file); return 0; }
static int vzctl_check_owner_quiet(const char *ve_private, char *serverid, size_t size, char *ve_ownerid, size_t ve_size) { char file[PATH_MAX]; char *p; int len; FILE *fp; int ret; ret = is_shared_fs(ve_private); if (ret == -1) { if (errno == ENOENT) return 0; return VZCTL_E_SYSTEM; } else if (ret == 0) return 0; snprintf(file, sizeof(file), "%s/" VZCTL_VE_OWNER, ve_private); if ((fp = fopen(file, "r")) == NULL) { /* CT is not registered */ if (errno == ENOENT) return 0; return vzctl_err(VZCTL_E_SYSTEM, errno, "Owner check failed, unable open file %s", file); } len = TEMP_FAILURE_RETRY(fread(ve_ownerid, 1, ve_size - 1, fp)); fclose(fp); if (len == -1) { return vzctl_err(VZCTL_E_SYSTEM, errno, "Unable to read owner from %s", file); } ve_ownerid[len] = '\0'; if ((p = strchr(ve_ownerid, '\n')) != NULL) *p = 0; if (vzctl2_get_normalized_uuid(ve_ownerid, file, sizeof(file))) { if (get_hostname(serverid, size - 1)) return vzctl_err(VZCTL_E_ENV_MANAGE_DISABLED, errno, "Owner check failed, unable to get hostname"); } else { get_serverid(serverid, size); } if (strcmp(serverid, ve_ownerid)) return VZCTL_E_ENV_MANAGE_DISABLED; return 0; }
static int parse_feature(struct vzctl_features_param *features, const char *str) { int id, len; const char *p; struct feature_s *f; char name[STR_SIZE]; p = strrchr(str, ':'); if (p == NULL) goto err; len = p - str; if (len >= sizeof(name)) len = sizeof(name) - 1; strncpy(name, str, len); name[len] = 0; f = find_feature(name); if (f == NULL) goto err; id = onoff2id(p + 1); if (id == -1) goto err; if (id == VZCTL_PARAM_ON) features->mask |= f->mask; features->known |= f->mask; return 0; err: return vzctl_err(VZCTL_E_INVAL, 0, "An incorrect feature syntax: %s", str); }
int vzctl2_env_set_features(struct vzctl_env_param *env, struct vzctl_feature_param *param) { struct vzctl_features_param *f = env->features; if (check_features_mask(param->on)) return vzctl_err(VZCTL_E_INVAL, 0, "An invalid feature on=%#llx is specified", param->on); if (check_features_mask(param->off)) return vzctl_err(VZCTL_E_INVAL, 0, "An invalid feature off=%#llx is specified", param->off); f->mask = param->on; f->known = param->on | param->off; return 0; }
static int get_hostname(char *out, int len) { struct hostent *he; char buf[STR_SIZE]; if (gethostname(buf, sizeof(buf) - 1)) return vzctl_err(-1, errno, "get_hostname function returned error"); pthread_mutex_lock(&_g_hostname_mtx); if (strncmp(_g_hostname, buf, strlen(buf))) { he = gethostbyname(buf); if (he != NULL) snprintf(_g_hostname, sizeof(_g_hostname), "%s", he->h_name); else if (strrchr(buf, '.')) snprintf(_g_hostname, sizeof(_g_hostname), "%s", buf); else { /* use name from gethostname() as is, not cached */ snprintf(out, len, "%s", buf); goto out; } } snprintf(out, len, "%s", _g_hostname); out: pthread_mutex_unlock(&_g_hostname_mtx); return 0; }
int vzctl2_get_env_status(const ctid_t ctid, vzctl_env_status_t *status, int mask) { char path[STR_SIZE]; int ret; struct vzctl_env_handle *h; ctid_t id; struct stat st; int flags = mask == ENV_STATUS_RUNNING ? VZCTL_CONF_SKIP_PARSE : 0; if (vzctl2_parse_ctid(ctid, id)) return vzctl_err(VZCTL_E_INVAL, 0, "Invalid CTID: %s", ctid); memset(status, 0, sizeof(struct vzctl_env_status)); vzctl2_get_env_conf_path(id, path, sizeof(path)); if (lstat(path, &st)) return 0; h = vzctl2_env_open(ctid, flags, &ret); if (h == NULL) return ret; ret = vzctl2_get_env_status_info(h, status, mask); vzctl2_env_close(h); return ret; }
static int get_env_ids_proc(vzctl_ids_t *ctids) { FILE *fp; char buf[256]; int res, classid, nproc; int ret; ctid_t ctid, id; if ((fp = fopen(PROC_VEINFO, "r")) == NULL) return vzctl_err(-2, errno, "Unabel to open" PROC_VEINFO); ret = 0; while (1) { if (fgets(buf, sizeof(buf), fp) == NULL) { if (!feof(fp)) ret = -1; break; } res = sscanf(buf, "%37s %d %d", id, &classid, &nproc); if (res != 3 || vzctl2_parse_ctid(id, ctid) || !strcmp(id, "0")) continue; if (add_eids(ctids, ctid, ++ret)) { ret = -1; break; } } fclose(fp); return ret; }
/* Authenticate the user in a the Container * @param id Container id * @param user User name * @param password User password * @param gid if >= 0 user checked to be a member of group gid. * @param type 0 - system, 1 - pleskadmin * @return */ int vzctl2_env_auth(struct vzctl_env_handle *h, const char *user, const char *passwd, int gid, int type) { int is_mounted = 0; int pid, ret; struct vzctl_env_param *env; if (user == NULL || passwd == NULL) return vzctl_err(VZCTL_E_INVAL, 0, "Invalid argument"); env = vzctl2_get_env_param(h); if (check_var(env->fs->ve_root, "VE_ROOT is not set")) return VZCTL_E_VE_ROOT_NOTSET; is_mounted = vzctl2_env_is_mounted(h); if (!is_mounted) { ret = vzctl2_env_mount(h, 0); if (ret) return ret; } if (!(pid = fork())) { int rootfd = -1; if (type == 0) { rootfd = open("/", O_RDONLY); if (rootfd == -1) _exit(vzctl_err(VZCTL_E_SYSTEM, errno, "failed to open '/' ")); } if ((ret = vzctl_chroot(env->fs->ve_root)) == 0) { if (type == 0) ret = userauth(user, passwd, gid, rootfd); else ret = pleskauth(user, passwd); } if (rootfd != -1) close(rootfd); _exit(ret); } ret = env_wait(pid, 0, NULL); if (!is_mounted) vzctl2_env_umount(h, 0); return ret; }
static int escape_chroot(int rootfd) { int ret = fchdir(rootfd); if (ret == -1) return vzctl_err(VZCTL_E_SYSTEM, errno, "fchdir('/') failed"); ret = chroot("."); if (ret == -1) logger(VZCTL_E_SYSTEM, errno, "chroot('/') failed"); return ret; }
int main(int argc, char **argv) { int ret; const char *action; ctid_t ctid = {}; struct vzctl_env_handle *h; if (argc < 3) return usage(); /* Action */ action = argv[1]; /* CTID */ if (vzctl2_parse_ctid(argv[2], ctid)) return VZCTL_E_INVAL; vzctl2_init_log(basename(argv[0])); vzctl2_set_ctx(ctid); if ((ret = vzctl2_lib_init())) return ret; vzctl2_set_flags(VZCTL_FLAG_DONT_USE_WRAP); h = vzctl2_env_open(ctid, 0, &ret); if (h == NULL) return ret; argc -= 3; argv += 3; if (!strcmp(action, "start")) ret = vzctl2_unwrap_env_start(h, argc, argv); else if (!strcmp(action, "stop")) ret = vzctl2_unwrap_env_stop(h, argc, argv); else if (!strcmp(action, "chkpnt")) ret = vzctl2_unwrap_env_chkpnt(h, argc, argv); else if (!strcmp(action, "restore")) ret = vzctl2_unwrap_env_restore(h, argc, argv); else if (!strcmp(action, "destroy")) ret = vzctl2_unwrap_env_destroy(h, argc, argv); else if (!strcmp(action, "create-snapshot")) ret = vzctl2_unwrap_env_create_snapshot(h, argc, argv); else if (!strcmp(action, "delete-snapshot")) ret = vzctl2_unwrap_env_delete_snapshot(h, argc, argv); else if (!strcmp(action, "switch-snapshot")) ret = vzctl2_unwrap_env_switch_snapshot(h, argc, argv); else ret = vzctl_err(VZCTL_E_INVAL_PARAMETER_SYNTAX, 0, "Unknown action: %s", action); vzctl2_env_close(h); return ret; }
int xstrdup(char **dst, const char *src) { char *t; if (src == NULL || *dst == src) return 0; if ((t = strdup(src)) == NULL) return vzctl_err(VZCTL_E_NOMEM, ENOMEM, "xstrdup"); if (*dst != NULL) free(*dst); *dst = t; return 0; }
static int unregister_env_conf(struct vzctl_env_handle *h) { char veconf[PATH_MAX]; get_env_conf_lockfile(h, veconf, sizeof(veconf)); unlink(veconf); vzctl2_get_env_conf_path(EID(h), veconf, sizeof(veconf)); if (unlink(veconf) && errno != ENOENT) return vzctl_err(VZCTL_E_SYSTEM, errno, "Failed to unlink %s", veconf); return 0; }
int vzctl2_env_unregister(const char *path, const ctid_t ctid, int flags) { int ret; struct vzctl_env_handle *h; h = vzctl2_env_open(ctid, 0, &ret); if (h == NULL) return vzctl_err(ret, 0, "failed to open Container %s configuration file", ctid); ret = vzctl2_env_unreg(h, flags); vzctl2_env_close(h); return ret; }
int vzctl2_check_owner(const char *ve_private) { int ret; char ve_host[STR_SIZE] = ""; char host[STR_SIZE] = ""; if (ve_private == NULL) return vzctl_err(VZCTL_E_VE_PRIVATE_NOTSET, 0, "Owner check failed:" " Container private area is not set"); ret = vzctl_check_owner_quiet(ve_private, host, sizeof(host), ve_host, sizeof(ve_host)); if (ret == VZCTL_E_ENV_MANAGE_DISABLED) logger(-1, 0, "Owner check failed on the server '%s':" " Container (%s) is registered for '%s'", host, ve_private, ve_host); return ret; }
struct vzctl_vz_env_param *alloc_vz_env_param(void) { struct vzctl_vz_env_param *env; if ((env = calloc(1, sizeof(struct vzctl_vz_env_param))) == NULL) goto err; if ((env->tc = alloc_tc_param()) == NULL) goto err; return env; err: free_vz_env_param(env); vzctl_err(VZCTL_E_NOMEM, ENOMEM, "vzctl_alloc_env_param"); return NULL; }
static int add_eids(vzctl_ids_t *ctids, ctid_t ctid, unsigned cnt) { void *t; if (cnt > ctids->size) { unsigned size = ctids->size + 100; t = realloc(ctids->ids, size * sizeof(ctid_t)); if (t == NULL) return vzctl_err(-1, ENOMEM, "get_env_ids_proc"); ctids->size = size; ctids->ids = t; } SET_CTID(ctids->ids[cnt - 1], ctid); return 0; }
int vzctl2_lib_init(void) { int ret; if (_initialized) return 0; init_env_ops(); if (get_env_ops()->open == NULL) return vzctl_err(VZCTL_E_BAD_KERNEL, 0, "Your kernel does not support working with virtual" " environments or necessary modules are not loaded"); ret = get_env_ops()->open(); if (ret) return ret; _initialized = 1; return 0; }
static int validate_eid(struct vzctl_env_handle *h, struct stat *veconf, ctid_t ctid) { char conf[PATH_MAX]; struct stat st; ctid_t ctid_conf; const char *data; if (vzctl2_env_get_param(h, "VEID", &data) == 0 && data != NULL) vzctl2_parse_ctid(data, ctid_conf); /* Check if VE_PRIVATE/ve.conf already registered * /etc/vz/conf/ctid_conf.conf -> VE_PRIVATE/ve.conf */ if (!EMPTY_CTID(ctid_conf)) { vzctl2_get_env_conf_path(ctid_conf, conf, sizeof(conf)); if (stat(conf, &st) == 0) { if (cmp_stat(veconf, &st) == 0) return vzctl_err(-1, 0, "Container is already" " registered with id %s", ctid_conf); } else if (errno != ENOENT) return vzctl_err(-1, errno, "Failed to stat %s", conf); } /* Check if ctid alredy used */ vzctl2_get_env_conf_path(ctid, conf, sizeof(conf)); if (lstat(conf, &st)) { if (errno == ENOENT) return 0; return vzctl_err(-1, errno, "Failed lstat %s", conf); } else if (!S_ISLNK(st.st_mode)) return vzctl_err(-1, 0, "Container configuration file %s" " is not a link", conf); if (stat(conf, &st)) { if (errno == ENOENT) return 0; return vzctl_err(-1, errno, "Failed to stat %s", conf); } /* /etc/vz/conf/ctid.conf already exists */ if (cmp_stat(veconf, &st) != 0 ) return vzctl_err(-1, 0, "Error: Container ID %s is used", ctid); return 0; }
int vzctl2_get_free_envid(unsigned *neweid, const char *dst, const char *unused) { int i; struct vzctl_conf_simple conf; char file[STR_SIZE]; char lckfile[STR_SIZE]; char dstlck[PATH_MAX]; struct stat st; int check_ve_private = 0; int check_ve_root = 0; int check_dst = 0; int fail_cnt = 0; int fd; ctid_t ctid = {}; vzctl_parse_conf_simple(ctid, GLOBAL_CFG, &conf); if (conf.ve_private_orig != NULL && strstr(conf.ve_private_orig, "$VEID")) check_ve_private = 1; if (conf.ve_root_orig != NULL && strstr(conf.ve_root_orig, "$VEID")) check_ve_root = 1; if (dst != NULL && strstr(dst, "$VEID")) { snprintf(dstlck, sizeof(dstlck), "%s.lck", dst); check_dst = 1; } *neweid = 0; for (i = START_ID; i < INT_MAX/2 && fail_cnt < GET_FREE_ENVID_FAIL_MAX; i++) { ctid_t ctid = {i, }; /* Check for VEID.conf */ vzctl2_get_env_conf_path(ctid, file, sizeof(file)); if (lstat(file, &st)) { if (errno != ENOENT) { logger(-1, errno, "Failed to stat %s", file); fail_cnt++; continue; } } else continue; /* lock envid */ snprintf(lckfile, sizeof(lckfile), "%s.lck", file); fd = open(lckfile, O_CREAT|O_EXCL, 0644); if (fd == -1) { if (errno != EEXIST) { fail_cnt++; logger(-1, errno, "Failed to create %s", lckfile); } continue; } close(fd); /* check if PATH(s) exist */ if ((check_ve_private && !is_dst_free(conf.ve_private_orig, ctid, &fail_cnt)) || (check_ve_root && !is_dst_free(conf.ve_root_orig, ctid, &fail_cnt)) || (check_dst && (!is_dst_free(dst, ctid, &fail_cnt) || !is_dst_free(dstlck, ctid, &fail_cnt)))) { /* unlock envid */ unlink(lckfile); continue; } *neweid = i; break; } vzctl_free_conf_simple(&conf); if (*neweid == 0) return vzctl_err(-1, 0, "Failed to get unused Countainer id"); return 0; }
int vzctl2_env_unreg(struct vzctl_env_handle *h, int flags) { char buf[STR_SIZE]; char host[STR_SIZE]; int ret; const char *ve_root; const char *ve_private = h->env_param->fs->ve_private; /* 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 (is_env_run(h)) return vzctl_err(VZCTL_E_ENV_RUN, 0, "Container is running, Stop Container before proceeding."); if (access(ve_private, F_OK) && errno == ENOENT) { ret = unregister_env_conf(h); if (ret) return ret; goto out; } if (vzctl2_env_layout_version(ve_private) < VZCTL_LAYOUT_4) return 0; ret = vzctl_check_owner_quiet(ve_private, buf, sizeof(buf), host, sizeof(host)); if (ret == VZCTL_E_ENV_MANAGE_DISABLED) { logger(0, 0, "Owner check failed on the server '%s':" " Container (%s) is registered for '%s'", buf, ve_private, host); ret = unregister_env_conf(h); if (ret) return ret; goto out; } else if (ret) return ret; ve_root = h->env_param->fs->ve_root; if (ve_root != NULL && vzctl2_env_is_mounted(h) == 1) { if (vzctl2_env_umount(h, 0)) return vzctl_err(VZCTL_E_FS_MOUNTED, 0, "Container is mounted, Unmount Container " "before proceeding."); } if (!(flags & VZ_UNREG_PRESERVE)) { /* Remove VEID from /ve_private/ve.conf */ vzctl2_env_set_param(h, "VEID", NULL); if (vzctl2_env_save(h)) return VZCTL_E_UNREGISTER; /* Remove VE_PRIVATE/.owner */ snprintf(buf, sizeof(buf), "%s/" VZCTL_VE_OWNER, ve_private); unlink(buf); } /* cleanup name */ if (h->env_param->name->name != NULL) { char name_path[PATH_MAX]; char veconf[PATH_MAX]; snprintf(veconf, sizeof(veconf), "%s/" VZCTL_VE_CONF, ve_private); snprintf(name_path, sizeof(name_path), ENV_NAME_DIR "%s", h->env_param->name->name); if (is_same_file(name_path, veconf)) unlink(name_path); } /* Remove /etc/vz/conf/VEID.conf */ unregister_env_conf(h); if (!(flags & VZ_REG_SKIP_CLUSTER) && is_shared_fs(ve_private) && shaman_del_resource(EID(h))) logger(0, 0,"Warning: Failed to unregister the Container on HA cluster"); out: vzctl2_destroy_net_stat(h, 0); vzctl2_send_state_evt(EID(h), VZCTL_ENV_UNREGISTERED); logger(0, 0, "Container unregistered succesfully"); return 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; }
int exec_container_init(struct arg_start *arg, struct env_create_param3 *create_param) { int fd, ret; char *argv[] = {"init", "-z", " ", NULL}; char *envp[] = {"HOME=/", "TERM=linux", NULL}; struct statfs sfs; /* Clear supplementary group IDs */ setgroups(0, NULL); /* for 32-bit userspace running over 64-bit kernels */ set_personality32(); /* Create /fastboot to skip run fsck */ fd = open("/fastboot", O_CREAT | O_RDONLY, 0644); if (fd >= 0) close(fd); if (arg->res->misc.wait == YES) { if (add_reach_runlevel_mark()) { ret = VZ_WAIT_FAILED; return -1; } } if (mkdir("/proc", 0555) && errno != EEXIST) return vzctl_err(VZ_SYSTEM_ERROR, errno, "Can't mkdir /proc"); if (statfs("/proc", &sfs)) return vzctl_err(VZ_SYSTEM_ERROR, errno, "statfs on /proc failed"); if (sfs.f_type != PROC_SUPER_MAGIC && mount("proc", "/proc", "proc", 0, 0)) return vzctl_err(VZ_SYSTEM_ERROR, errno, "Failed to mount /proc"); if (stat_file("/sys") == 1) mount("sysfs", "/sys", "sysfs", 0, 0); if (create_param->feature_mask & VE_FEATURE_NFSD) { mount("nfsd", "/proc/fs/nfsd", "nfsd", 0, 0); make_dir("/var/lib/nfs/rpc_pipefs", 1); mount("sunrpc", "/var/lib/nfs/rpc_pipefs", "rpc_pipefs", 0, 0); } write_val("/proc/sys/net/ipv6/conf/all/forwarding", "0"); /* Close status descriptor to report that * environment is created. */ close(STDIN_FILENO); /* Now we wait until CT setup will be done If no error, then start init, otherwise exit. */ if (read(arg->wait_p, &ret, sizeof(ret)) == 0) return -1; if ((fd = open("/dev/null", O_RDWR)) != -1) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); } logger(10, 0, "Starting init"); close_fds(0, arg->err_p, -1); execve("/sbin/init", argv, envp); execve("/etc/init", argv, envp); execve("/bin/init", argv, envp); ret = VZ_FS_BAD_TMPL; write(arg->err_p, &ret, sizeof(ret)); return ret; }