Пример #1
0
static int dump_one_packet_fd(int lfd, u32 id, const struct fd_parms *p)
{
	PacketSockEntry psk = PACKET_SOCK_ENTRY__INIT;
	SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
	struct packet_sock_desc *sd;
	int i, ret;

	sd = (struct packet_sock_desc *)lookup_socket(p->stat.st_ino, PF_PACKET, 0);
	if (IS_ERR_OR_NULL(sd)) {
		pr_err("Can't find packet socket %"PRIu64"\n", p->stat.st_ino);
		return -1;
	}

	pr_info("Dumping packet socket fd %d id %#x\n", lfd, id);
	BUG_ON(sd->sd.already_dumped);
	sd->sd.already_dumped = 1;

	psk.id = sd->file_id = id;
	psk.type = sd->type;
	psk.flags = p->flags;
	psk.fown = (FownEntry *)&p->fown;
	psk.opts = &skopts;

	if (dump_socket_opts(lfd, &skopts))
		return -1;

	psk.protocol = sd->proto;
	psk.ifindex = sd->nli.pdi_index;
	psk.version = sd->nli.pdi_version;
	psk.reserve = sd->nli.pdi_reserve;
	psk.timestamp = sd->nli.pdi_tstamp;
	psk.copy_thresh = sd->nli.pdi_copy_thresh;
	psk.aux_data = (sd->nli.pdi_flags & PDI_AUXDATA ? true : false);
	psk.orig_dev = (sd->nli.pdi_flags & PDI_ORIGDEV ? true : false);
	psk.vnet_hdr = (sd->nli.pdi_flags & PDI_VNETHDR ? true : false);
	psk.loss = (sd->nli.pdi_flags & PDI_LOSS ? true : false);

	ret = dump_mreqs(&psk, sd);
	if (ret)
		goto out;

	if (sd->fanout != NO_FANOUT) {
		psk.has_fanout = true;
		psk.fanout = sd->fanout;
	}

	ret = dump_rings(&psk, sd);
	if (ret)
		goto out;

	ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_PACKETSK), &psk, PB_PACKETSK);
out:
	release_skopts(&skopts);
	xfree(psk.rx_ring);
	xfree(psk.tx_ring);
	for (i = 0; i < psk.n_mclist; i++)
		xfree(psk.mclist[i]->addr.data);
	xfree(psk.mclist);
	return ret;
}
Пример #2
0
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
{
	struct parasite_dump_sa_args *args;
	int ret, sig, fd;
	SaEntry se = SA_ENTRY__INIT;

	args = parasite_args(ctl, struct parasite_dump_sa_args);

	ret = parasite_execute(PARASITE_CMD_DUMP_SIGACTS, ctl);
	if (ret < 0)
		return ret;

	fd = fdset_fd(cr_fdset, CR_FD_SIGACT);

	for (sig = 1; sig <= SIGMAX; sig++) {
		int i = sig - 1;

		if (sig == SIGSTOP || sig == SIGKILL)
			continue;

		ASSIGN_TYPED(se.sigaction, encode_pointer(args->sas[i].rt_sa_handler));
		ASSIGN_TYPED(se.flags, args->sas[i].rt_sa_flags);
		ASSIGN_TYPED(se.restorer, encode_pointer(args->sas[i].rt_sa_restorer));
		ASSIGN_TYPED(se.mask, args->sas[i].rt_sa_mask.sig[0]);

		if (pb_write_one(fd, &se, PB_SIGACT) < 0)
			return -1;
	}

	return 0;
}
Пример #3
0
static int dump_ipc_data(const struct cr_fdset *fdset)
{
	int ret;

	ret = dump_ipc_var(fdset_fd(fdset, CR_FD_IPC_VAR));
	if (ret < 0)
		return ret;
	ret = dump_ipc_shm(fdset_fd(fdset, CR_FD_IPCNS_SHM));
	if (ret < 0)
		return ret;
	ret = dump_ipc_msg(fdset_fd(fdset, CR_FD_IPCNS_MSG));
	if (ret < 0)
		return ret;
	ret = dump_ipc_sem(fdset_fd(fdset, CR_FD_IPCNS_SEM));
	if (ret < 0)
		return ret;
	return 0;
}
Пример #4
0
static int dump_eventfd_entry(union fdinfo_entries *e, void *arg)
{
	struct eventfd_dump_arg *da = arg;

	if (da->dumped) {
		pr_err("Several counters in a file?\n");
		return -1;
	}

	da->dumped = true;
	e->efd.id = da->id;
	e->efd.flags = da->p->flags;
	e->efd.fown = (FownEntry *)&da->p->fown;

	pr_info_eventfd("Dumping ", &e->efd);
	return pb_write_one(fdset_fd(glob_fdset, CR_FD_EVENTFD),
			&e->efd, PB_EVENTFD);
}
Пример #5
0
Файл: tun.c Проект: blindFS/criu
static int dump_tunfile(int lfd, u32 id, const struct fd_parms *p)
{
	int ret, img = fdset_fd(glob_fdset, CR_FD_TUNFILE);
	TunfileEntry tfe = TUNFILE_ENTRY__INIT;
	struct ifreq ifr;

	if (!(root_ns_mask & CLONE_NEWNET)) {
		pr_err("Net namespace is required to dump tun link\n");
		return -1;
	}

	if (dump_one_reg_file(lfd, id, p))
		return -1;

	pr_info("Dumping tun-file %d with id %#x\n", lfd, id);

	tfe.id		= id;
	ret = ioctl(lfd, TUNGETIFF, &ifr);
	if (ret < 0) {
		if (errno != EBADFD) {
			pr_perror("Can't dump tun-file device");
			return -1;
		}

		/*
		 * Otherwise this is just opened file with not yet attached
		 * tun device. Go agead an write the respective entry.
		 */
	} else {
		tfe.netdev = ifr.ifr_name;
		pr_info("`- attached to device %s (flags %x)\n", tfe.netdev, ifr.ifr_flags);

		if (ifr.ifr_flags & IFF_DETACH_QUEUE) {
			tfe.has_detached = true;
			tfe.detached = true;
		}

		if (dump_tun_link_fd(lfd, tfe.netdev, ifr.ifr_flags) == NULL)
			return -1;
	}

	return pb_write_one(img, &tfe, PB_TUNFILE);
}
Пример #6
0
int dump_one_ns_file(int lfd, u32 id, const struct fd_parms *p)
{
	int fd = fdset_fd(glob_fdset, CR_FD_NS_FILES);
	NsFileEntry nfe = NS_FILE_ENTRY__INIT;
	struct fd_link *link = p->link;
	unsigned int nsid;

	nsid = lookup_ns_id(link->ns_kid, link->ns_d);
	if (!nsid) {
		pr_err("No NS ID with kid %u\n", link->ns_kid);
		return -1;
	}

	nfe.id		= id;
	nfe.ns_id	= nsid;
	nfe.ns_cflag	= link->ns_d->cflag;
	nfe.flags	= p->flags;

	return pb_write_one(fd, &nfe, PB_NS_FILE);
}
Пример #7
0
int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
{
	struct parasite_dump_itimers_args *args;
	int ret, fd;

	args = parasite_args(ctl, struct parasite_dump_itimers_args);

	ret = parasite_execute(PARASITE_CMD_DUMP_ITIMERS, ctl);
	if (ret < 0)
		return ret;

	fd = fdset_fd(cr_fdset, CR_FD_ITIMERS);

	ret = dump_one_timer(&args->real, fd);
	if (!ret)
		ret = dump_one_timer(&args->virt, fd);
	if (!ret)
		ret = dump_one_timer(&args->prof, fd);

	return ret;
}
Пример #8
0
int dump_uts_ns(int ns_pid, struct cr_fdset *fdset)
{
	int ret;
	struct utsname ubuf;
	UtsnsEntry ue = UTSNS_ENTRY__INIT;

	ret = switch_ns(ns_pid, CLONE_NEWUTS, "uts", NULL);
	if (ret < 0)
		return ret;

	ret = uname(&ubuf);
	if (ret < 0) {
		pr_perror("Error calling uname");
		return ret;
	}

	ue.nodename = ubuf.nodename;
	ue.domainname = ubuf.domainname;

	return pb_write_one(fdset_fd(fdset, CR_FD_UTSNS), &ue, PB_UTSNS);
}
Пример #9
0
static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p)
{
	struct netlink_sk_desc *sk;
	NetlinkSkEntry ne = NETLINK_SK_ENTRY__INIT;
	SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;

	sk = (struct netlink_sk_desc *)lookup_socket(p->stat.st_ino, PF_NETLINK, 0);
	if (IS_ERR(sk))
		goto err;

	ne.id = id;
	ne.ino = p->stat.st_ino;

	if (!can_dump_netlink_sk(lfd))
		goto err;

	if (sk) {
		BUG_ON(sk->sd.already_dumped);

		ne.protocol = sk->protocol;
		ne.portid = sk->portid;
		ne.groups = sk->groups;


		ne.n_groups = sk->gsize / sizeof(ne.groups[0]);
		/*
		 * On 64-bit sk->gsize is multiple to 8 bytes (sizeof(long)),
		 * so remove the last 4 bytes if they are empty.
		 */
		if (ne.n_groups && sk->groups[ne.n_groups - 1] == 0)
			ne.n_groups -= 1;

		if (ne.n_groups > 1) {
			pr_err("%d %x\n", sk->gsize, sk->groups[1]);
			pr_err("The netlink socket 0x%x has more than 32 groups\n", ne.ino);
			return -1;
		}
		if (sk->groups && !sk->portid) {
			pr_err("The netlink socket 0x%x is bound to groups but not to portid\n", ne.ino);
			return -1;
		}
		ne.state = sk->state;
		ne.dst_portid = sk->dst_portid;
		ne.dst_group = sk->dst_group;
	} else { /* unconnected and unbound socket */
		int val;
		socklen_t aux = sizeof(val);

		if (getsockopt(lfd, SOL_SOCKET, SO_PROTOCOL, &val, &aux) < 0) {
			pr_perror("Unable to get protocol for netlink socket");
			goto err;
		}

		ne.protocol = val;
	}

	ne.fown = (FownEntry *)&p->fown;
	ne.opts	= &skopts;

	if (dump_socket_opts(lfd, &skopts))
		goto err;

	if (pb_write_one(fdset_fd(glob_fdset, CR_FD_NETLINK_SK), &ne, PB_NETLINK_SK))
		goto err;

	return 0;
err:
	return -1;
}