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; }
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; }
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; }
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); }
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); }
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); }
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; }
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); }
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; }