Beispiel #1
0
int check_img_inventory(void)
{
	int fd, ret = -1;
	InventoryEntry *he;

	fd = open_image(CR_FD_INVENTORY, O_RSTR);
	if (fd < 0)
		return -1;

	if (pb_read_one(fd, &he, PB_INVENTORY) < 0)
		goto out_close;

	fdinfo_per_id = he->has_fdinfo_per_id ?  he->fdinfo_per_id : false;
	ns_per_id = he->has_ns_per_id ? he->ns_per_id : false;

	if (he->root_ids) {
		root_ids = xmalloc(sizeof(*root_ids));
		if (!root_ids)
			goto out_err;

		memcpy(root_ids, he->root_ids, sizeof(*root_ids));
	}

	if (he->img_version != CRTOOLS_IMAGES_V1) {
		pr_err("Not supported images version %u\n", he->img_version);
		goto out_err;
	}
	ret = 0;

out_err:
	inventory_entry__free_unpacked(he, NULL);
out_close:
	close(fd);
	return ret;
}
Beispiel #2
0
static int prepare_ipc_var(int pid)
{
	int ret;
	struct cr_img *img;
	IpcVarEntry *var;

	pr_info("Restoring IPC variables\n");
	img = open_image(CR_FD_IPC_VAR, O_RSTR, pid);
	if (!img)
		return -1;

	ret = pb_read_one(img, &var, PB_IPC_VAR);
	close_image(img);
	if (ret <= 0) {
		pr_err("Failed to read IPC namespace variables\n");
		return -EFAULT;
	}

	ret = ipc_sysctl_req(var, CTL_WRITE);
	ipc_var_entry__free_unpacked(var, NULL);

	if (ret < 0) {
		pr_err("Failed to prepare IPC namespace variables\n");
		return -EFAULT;
	}

	return 0;
}
Beispiel #3
0
int prepare_utsns(int pid)
{
	int fd, ret;
	UtsnsEntry *ue;
	struct sysctl_req req[3] = {
		{ "kernel/hostname" },
		{ "kernel/domainname" },
		{ },
	};

	fd = open_image_ro(CR_FD_UTSNS, pid);
	if (fd < 0)
		return -1;

	ret = pb_read_one(fd, &ue, PB_UTSNS);
	if (ret < 0)
		goto out;

	req[0].arg = ue->nodename;
	req[0].type = CTL_STR(strlen(ue->nodename));
	req[1].arg = ue->domainname;
	req[1].type = CTL_STR(strlen(ue->domainname));

	ret = sysctl_op(req, CTL_WRITE);
	utsns_entry__free_unpacked(ue, NULL);
out:
	close(fd);
	return ret;
}
Beispiel #4
0
int prepare_utsns(int pid)
{
	int ret;
	struct cr_img *img;
	UtsnsEntry *ue;
	struct sysctl_req req[] = {
		{ "kernel/hostname" },
		{ "kernel/domainname" },
	};

	img = open_image(CR_FD_UTSNS, O_RSTR, pid);
	if (!img)
		return -1;

	ret = pb_read_one(img, &ue, PB_UTSNS);
	if (ret < 0)
		goto out;

	req[0].arg = ue->nodename;
	req[0].type = CTL_STR(strlen(ue->nodename));
	req[1].arg = ue->domainname;
	req[1].type = CTL_STR(strlen(ue->domainname));

	ret = sysctl_op(req, ARRAY_SIZE(req), CTL_WRITE, CLONE_NEWUTS);
	utsns_entry__free_unpacked(ue, NULL);
out:
	close_image(img);
	return ret;
}
Beispiel #5
0
int check_img_inventory(void)
{
	int ret = -1;
	struct cr_img *img;
	InventoryEntry *he;

	img = open_image(CR_FD_INVENTORY, O_RSTR);
	if (!img)
		return -1;

	if (pb_read_one(img, &he, PB_INVENTORY) < 0)
		goto out_close;

	fdinfo_per_id = he->has_fdinfo_per_id ?  he->fdinfo_per_id : false;
	ns_per_id = he->has_ns_per_id ? he->ns_per_id : false;

	if (he->root_ids) {
		root_ids = xmalloc(sizeof(*root_ids));
		if (!root_ids)
			goto out_err;

		memcpy(root_ids, he->root_ids, sizeof(*root_ids));
	}

	if (he->has_root_cg_set) {
		if (he->root_cg_set == 0) {
			pr_err("Corrupted root cgset\n");
			goto out_err;
		}

		root_cg_set = he->root_cg_set;
	}

	image_lsm = he->lsmtype;

	switch (he->img_version) {
	case CRTOOLS_IMAGES_V1:
		/* good old images. OK */
		img_common_magic = false;
		break;
	case CRTOOLS_IMAGES_V1_1:
		/* newer images with extra magic in the head */
		break;
	default:
		pr_err("Not supported images version %u\n", he->img_version);
		goto out_err;
	}

	ret = 0;

out_err:
	inventory_entry__free_unpacked(he, NULL);
out_close:
	close_image(img);
	return ret;
}
Beispiel #6
0
static void show_inventory(int fd, struct cr_options *o)
{
	InventoryEntry *he;

	if (pb_read_one(fd, &he, PB_INVENTORY) < 0)
		return;

	pr_msg("Version: %u\n", he->img_version);
	inventory_entry__free_unpacked(he, NULL);
}
Beispiel #7
0
static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii)
{
	int ifd, aux;
	TcpStreamEntry *tse;

	pr_info("Restoring TCP connection id %x ino %x\n", ii->ie->id, ii->ie->ino);

	ifd = open_image(CR_FD_TCP_STREAM, O_RSTR, ii->ie->ino);
	if (ifd < 0)
		goto err;

	if (pb_read_one(ifd, &tse, PB_TCP_STREAM) < 0)
		goto err_c;

	if (restore_tcp_seqs(sk, tse))
		goto err_c;

	if (inet_bind(sk, ii))
		goto err_c;

	if (inet_connect(sk, ii))
		goto err_c;

	if (restore_tcp_opts(sk, tse))
		goto err_c;

	if (restore_tcp_queues(sk, tse, ifd))
		goto err_c;

	if (tse->has_nodelay && tse->nodelay) {
		aux = 1;
		if (restore_opt(sk, SOL_TCP, TCP_NODELAY, &aux))
			goto err_c;
	}

	if (tse->has_cork && tse->cork) {
		aux = 1;
		if (restore_opt(sk, SOL_TCP, TCP_CORK, &aux))
			goto err_c;
	}

	tcp_stream_entry__free_unpacked(tse, NULL);
	close(ifd);
	return 0;

err_c:
	tcp_stream_entry__free_unpacked(tse, NULL);
	close(ifd);
err:
	return -1;
}
Beispiel #8
0
static int open_remap_ghost(struct reg_file_info *rfi,
					RemapFilePathEntry *rfe)
{
	struct ghost_file *gf = container_of(rfi->remap, struct ghost_file, remap);
	GhostFileEntry *gfe = NULL;
	struct cr_img *img;

	if (rfi->remap->rpath[0])
		return 0;

	img = open_image(CR_FD_GHOST_FILE, O_RSTR, rfe->remap_id);
	if (!img)
		goto err;

	if (pb_read_one(img, &gfe, PB_GHOST_FILE) < 0)
		goto close_ifd;

	/*
	 * For old formats where optional has_[dev|ino] is
	 * not present we will have zeros here which is quite
	 * a sign for "absent" fields.
	 */
	gf->dev = gfe->dev;
	gf->ino = gfe->ino;
	gf->remap.rmnt_id = rfi->rfe->mnt_id;

	if (S_ISDIR(gfe->mode))
		strncpy(gf->remap.rpath, rfi->path, PATH_MAX);
	else
		ghost_path(gf->remap.rpath, PATH_MAX, rfi, rfe);

	if (create_ghost(gf, gfe, img))
		goto close_ifd;

	close_image(img);

	gf->remap.is_dir = S_ISDIR(gfe->mode);
	gf->remap.uid = gfe->uid;
	gf->remap.gid = gfe->gid;
	ghost_file_entry__free_unpacked(gfe, NULL);

	return 0;

close_ifd:
	close_image(img);
err:
	if (gfe)
		ghost_file_entry__free_unpacked(gfe, NULL);
	return -1;
}
Beispiel #9
0
struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *pmi, u32 *id)
{
	if (flags == O_RDONLY || flags == O_RDWR) {
		PagemapHead *h;
		if (pb_read_one(pmi, &h, PB_PAGEMAP_HEAD) < 0)
			return NULL;
		*id = h->pages_id;
		pagemap_head__free_unpacked(h, NULL);
	} else {
		PagemapHead h = PAGEMAP_HEAD__INIT;
		*id = h.pages_id = page_ids++;
		if (pb_write_one(pmi, &h, PB_PAGEMAP_HEAD) < 0)
			return NULL;
	}

	return open_image_at(dfd, CR_FD_PAGES, flags, *id);
}
Beispiel #10
0
static int prepare_ipc_msg_queue_messages(struct cr_img *img, const IpcMsgEntry *msq)
{
	IpcMsg *msg = NULL;
	int msg_nr = 0;
	int ret = 0;

	while (msg_nr < msq->qnum) {
		struct msgbuf {
			long mtype;
			char mtext[MSGMAX];
		} data;

		ret = pb_read_one(img, &msg, PB_IPCNS_MSG);
		if (ret <= 0)
			return -EIO;

		pr_info_ipc_msg(msg_nr, msg);

		if (msg->msize > MSGMAX) {
			ret = -1;
			pr_err("Unsupported message size: %d (MAX: %d)\n",
						msg->msize, MSGMAX);
			break;
		}

		ret = read_img_buf(img, data.mtext, round_up(msg->msize, sizeof(u64)));
		if (ret < 0) {
			pr_err("Failed to read IPC message data\n");
			break;
		}

		data.mtype = msg->mtype;
		ret = msgsnd(msq->desc->id, &data, msg->msize, IPC_NOWAIT);
		if (ret < 0) {
			pr_perror("Failed to send IPC message");
			ret = -errno;
			break;
		}
		msg_nr++;
	}

	if (msg)
		ipc_msg__free_unpacked(msg, NULL);
	return ret;
}
Beispiel #11
0
int open_pages_image_at(int dfd, unsigned long flags, int pm_fd)
{
	unsigned id;

	if (flags == O_RDONLY || flags == O_RDWR) {
		PagemapHead *h;
		if (pb_read_one(pm_fd, &h, PB_PAGEMAP_HEAD) < 0)
			return -1;
		id = h->pages_id;
		pagemap_head__free_unpacked(h, NULL);
	} else {
		PagemapHead h = PAGEMAP_HEAD__INIT;
		id = h.pages_id = page_ids++;
		if (pb_write_one(pm_fd, &h, PB_PAGEMAP_HEAD) < 0)
			return -1;
	}

	return open_image_at(dfd, CR_FD_PAGES, flags, id);
}
Beispiel #12
0
Datei: cpu.c Projekt: avagin/criu
int cpu_validate_cpuinfo(void)
{
	CpuinfoX86Entry *img_x86_entry;
	CpuinfoEntry *img_cpu_info;
	struct cr_img *img;
	int ret = -1;

	img = open_image(CR_FD_CPUINFO, O_RSTR);
	if (!img)
		return -1;

	if (pb_read_one(img, &img_cpu_info, PB_CPUINFO) < 0)
		goto err;

	if (img_cpu_info->n_x86_entry != 1) {
		pr_err("No x86 related cpuinfo in image, "
		       "corruption (n_x86_entry = %zi)\n",
		       img_cpu_info->n_x86_entry);
		goto err;
	}

	img_x86_entry = img_cpu_info->x86_entry[0];
	if (img_x86_entry->vendor_id != CPUINFO_X86_ENTRY__VENDOR__INTEL &&
	    img_x86_entry->vendor_id != CPUINFO_X86_ENTRY__VENDOR__AMD) {
		pr_err("Unknown cpu vendor %d\n", img_x86_entry->vendor_id);
		goto err;
	}

	if (img_x86_entry->n_capability != ARRAY_SIZE(rt_cpu_info.x86_capability)) {
		pr_err("Image carries %u words while %u expected\n",
		       (unsigned)img_x86_entry->n_capability,
		       (unsigned)ARRAY_SIZE(rt_cpu_info.x86_capability));
		goto err;
	}

	ret = cpu_validate_features(img_x86_entry);
err:
	close_image(img);
	return ret;
}
Beispiel #13
0
int check_img_inventory(void)
{
	int fd, ret;
	InventoryEntry *he;

	fd = open_image_ro(CR_FD_INVENTORY);
	if (fd < 0)
		return -1;

	ret = pb_read_one(fd, &he, PB_INVENTORY);
	close(fd);
	if (ret < 0)
		return ret;

	ret = he->img_version;
	inventory_entry__free_unpacked(he, NULL);

	if (ret != CRTOOLS_IMAGES_V1) {
		pr_err("Not supported images version %u\n", ret);
		return -1;
	}

	return 0;
}
Beispiel #14
0
InventoryEntry *get_parent_inventory(void)
{
	struct cr_img *img;
	InventoryEntry *ie;
	int dir;

	dir = openat(get_service_fd(IMG_FD_OFF), CR_PARENT_LINK, O_RDONLY);
	if (dir == -1) {
		pr_warn("Failed to open parent directory\n");
		return NULL;
	}

	img = open_image_at(dir, CR_FD_INVENTORY, O_RSTR);
	if (!img) {
		pr_warn("Failed to open parent pre-dump inventory image\n");
		close(dir);
		return NULL;
	}

	if (pb_read_one(img, &ie, PB_INVENTORY) < 0) {
		pr_warn("Failed to read parent pre-dump inventory entry\n");
		close_image(img);
		close(dir);
		return NULL;
	}

	if (!ie->has_dump_uptime) {
		pr_warn("Parent pre-dump inventory has no uptime\n");
		inventory_entry__free_unpacked(ie, NULL);
		ie = NULL;
	}

	close_image(img);
	close(dir);
	return ie;
}
Beispiel #15
0
static int open_remap_ghost(struct reg_file_info *rfi,
		RemapFilePathEntry *rfe)
{
	struct ghost_file *gf;
	GhostFileEntry *gfe = NULL;
	struct cr_img *img;

	list_for_each_entry(gf, &ghost_files, list)
		if (gf->id == rfe->remap_id)
			goto gf_found;

	/*
	 * Ghost not found. We will create one in the same dir
	 * as the very first client of it thus resolving any
	 * issues with cross-device links.
	 */

	pr_info("Opening ghost file %#x for %s\n", rfe->remap_id, rfi->path);

	gf = shmalloc(sizeof(*gf));
	if (!gf)
		return -1;

	gf->remap.rpath = xmalloc(PATH_MAX);
	if (!gf->remap.rpath)
		goto err;

	img = open_image(CR_FD_GHOST_FILE, O_RSTR, rfe->remap_id);
	if (!img)
		goto err;

	if (pb_read_one(img, &gfe, PB_GHOST_FILE) < 0)
		goto close_ifd;

	/*
	 * For old formats where optional has_[dev|ino] is
	 * not present we will have zeros here which is quite
	 * a sign for "absent" fields.
	 */
	gf->dev = gfe->dev;
	gf->ino = gfe->ino;
	gf->remap.rmnt_id = rfi->rfe->mnt_id;

	if (S_ISDIR(gfe->mode))
		strncpy(gf->remap.rpath, rfi->path, PATH_MAX);
	else
		ghost_path(gf->remap.rpath, PATH_MAX, rfi, rfe);

	if (create_ghost(gf, gfe, img))
		goto close_ifd;

	ghost_file_entry__free_unpacked(gfe, NULL);
	close_image(img);

	gf->id = rfe->remap_id;
	gf->remap.users = 0;
	gf->remap.is_dir = S_ISDIR(gfe->mode);
	gf->remap.owner = gfe->uid;
	list_add_tail(&gf->list, &ghost_files);
gf_found:
	rfi->remap = &gf->remap;
	return 0;

close_ifd:
	close_image(img);
err:
	if (gfe)
		ghost_file_entry__free_unpacked(gfe, NULL);
	xfree(gf->remap.rpath);
	shfree_last(gf);
	return -1;
}
Beispiel #16
0
Datei: cpu.c Projekt: avagin/criu
int cpu_validate_cpuinfo(void)
{
	CpuinfoEntry *cpu_info;
	CpuinfoPpc64Entry *cpu_ppc64_entry;
	struct cr_img *img;
	int ret = -1;
        img = open_image(CR_FD_CPUINFO, O_RSTR);
        if (!img)
                return -1;

        if (pb_read_one(img, &cpu_info, PB_CPUINFO) < 0)
                goto error;

	if (cpu_info->n_ppc64_entry != 1) {
		pr_err("No PPC64 related entry in image");
		goto error;
	}
	cpu_ppc64_entry = cpu_info->ppc64_entry[0];

	if (cpu_ppc64_entry->endian != CURRENT_ENDIANNESS) {
		pr_err("Bad endianness");
		goto error;
	}

	if (cpu_ppc64_entry->n_hwcap != 2) {
		pr_err("Hardware capabilities information missing\n");
		goto error;
	}

#define CHECK_FEATURE(s,f) do {						\
		if ((cpu_ppc64_entry->hwcap[s] & f) &&			\
		    !(rt_cpuinfo.hwcap[s] & f)) {			\
			pr_err("CPU Feature %s required by image "	\
			       "is not supported on host.\n", #f);	\
			goto error;					\
		}							\
	} while(0)

#define REQUIRE_FEATURE(s,f) do {					\
		if (!(cpu_ppc64_entry->hwcap[s] & f)) {			\
			pr_err("CPU Feature %s missing in image.\n", #f); \
			goto error;					\
		}							\
	} while(0)

	REQUIRE_FEATURE(0, PPC_FEATURE_64);
	REQUIRE_FEATURE(0, PPC_FEATURE_HAS_FPU);
	REQUIRE_FEATURE(0, PPC_FEATURE_HAS_MMU);
	REQUIRE_FEATURE(0, PPC_FEATURE_HAS_VSX);
	REQUIRE_FEATURE(1, PPC_FEATURE2_ARCH_2_07);

	CHECK_FEATURE(0, PPC_FEATURE_TRUE_LE);
	CHECK_FEATURE(1, PPC_FEATURE2_HTM);
	CHECK_FEATURE(1, PPC_FEATURE2_DSCR);
	CHECK_FEATURE(1, PPC_FEATURE2_EBB);
	CHECK_FEATURE(1, PPC_FEATURE2_ISEL);
	CHECK_FEATURE(1, PPC_FEATURE2_TAR);
	CHECK_FEATURE(1, PPC_FEATURE2_VEC_CRYPTO);

	ret = 0;
error:
	close_image(img);
	return ret;
}