libprocstat.c (247602) | libprocstat.c (249666) |
---|---|
1/*- 2 * Copyright (c) 2009 Stanislav Sedov <stas@FreeBSD.org> 3 * Copyright (c) 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 19 unchanged lines hidden (view full) --- 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009 Stanislav Sedov <stas@FreeBSD.org> 3 * Copyright (c) 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 19 unchanged lines hidden (view full) --- 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/lib/libprocstat/libprocstat.c 247602 2013-03-02 00:53:12Z pjd $"); | 36__FBSDID("$FreeBSD: head/lib/libprocstat/libprocstat.c 249666 2013-04-20 07:47:26Z trociny $"); |
37 38#include <sys/param.h> 39#include <sys/time.h> 40#include <sys/proc.h> 41#include <sys/user.h> 42#include <sys/stat.h> 43#include <sys/vnode.h> 44#include <sys/socket.h> --- 46 unchanged lines hidden (view full) --- 91#include <stddef.h> 92#include <string.h> 93#include <unistd.h> 94#include <netdb.h> 95 96#include <libprocstat.h> 97#include "libprocstat_internal.h" 98#include "common_kvm.h" | 37 38#include <sys/param.h> 39#include <sys/time.h> 40#include <sys/proc.h> 41#include <sys/user.h> 42#include <sys/stat.h> 43#include <sys/vnode.h> 44#include <sys/socket.h> --- 46 unchanged lines hidden (view full) --- 91#include <stddef.h> 92#include <string.h> 93#include <unistd.h> 94#include <netdb.h> 95 96#include <libprocstat.h> 97#include "libprocstat_internal.h" 98#include "common_kvm.h" |
99#include "core.h" |
|
99 100int statfs(const char *, struct statfs *); /* XXX */ 101 102#define PROCSTAT_KVM 1 103#define PROCSTAT_SYSCTL 2 | 100 101int statfs(const char *, struct statfs *); /* XXX */ 102 103#define PROCSTAT_KVM 1 104#define PROCSTAT_SYSCTL 2 |
105#define PROCSTAT_CORE 3 |
|
104 105static char *getmnton(kvm_t *kd, struct mount *m); 106static struct filestat_list *procstat_getfiles_kvm( 107 struct procstat *procstat, struct kinfo_proc *kp, int mmapped); 108static struct filestat_list *procstat_getfiles_sysctl( 109 struct procstat *procstat, struct kinfo_proc *kp, int mmapped); 110static int procstat_get_pipe_info_sysctl(struct filestat *fst, 111 struct pipestat *pipe, char *errbuf); --- 20 unchanged lines hidden (view full) --- 132 133void 134procstat_close(struct procstat *procstat) 135{ 136 137 assert(procstat); 138 if (procstat->type == PROCSTAT_KVM) 139 kvm_close(procstat->kd); | 106 107static char *getmnton(kvm_t *kd, struct mount *m); 108static struct filestat_list *procstat_getfiles_kvm( 109 struct procstat *procstat, struct kinfo_proc *kp, int mmapped); 110static struct filestat_list *procstat_getfiles_sysctl( 111 struct procstat *procstat, struct kinfo_proc *kp, int mmapped); 112static int procstat_get_pipe_info_sysctl(struct filestat *fst, 113 struct pipestat *pipe, char *errbuf); --- 20 unchanged lines hidden (view full) --- 134 135void 136procstat_close(struct procstat *procstat) 137{ 138 139 assert(procstat); 140 if (procstat->type == PROCSTAT_KVM) 141 kvm_close(procstat->kd); |
142 else if (procstat->type == PROCSTAT_CORE) 143 procstat_core_close(procstat->core); |
|
140 free(procstat); 141} 142 143struct procstat * 144procstat_open_sysctl(void) 145{ 146 struct procstat *procstat; 147 --- 24 unchanged lines hidden (view full) --- 172 free(procstat); 173 return (NULL); 174 } 175 procstat->type = PROCSTAT_KVM; 176 procstat->kd = kd; 177 return (procstat); 178} 179 | 144 free(procstat); 145} 146 147struct procstat * 148procstat_open_sysctl(void) 149{ 150 struct procstat *procstat; 151 --- 24 unchanged lines hidden (view full) --- 176 free(procstat); 177 return (NULL); 178 } 179 procstat->type = PROCSTAT_KVM; 180 procstat->kd = kd; 181 return (procstat); 182} 183 |
184struct procstat * 185procstat_open_core(const char *filename) 186{ 187 struct procstat *procstat; 188 struct procstat_core *core; 189 190 procstat = calloc(1, sizeof(*procstat)); 191 if (procstat == NULL) { 192 warn("malloc()"); 193 return (NULL); 194 } 195 core = procstat_core_open(filename); 196 if (core == NULL) { 197 free(procstat); 198 return (NULL); 199 } 200 procstat->type = PROCSTAT_CORE; 201 procstat->core = core; 202 return (procstat); 203} 204 |
|
180struct kinfo_proc * 181procstat_getprocs(struct procstat *procstat, int what, int arg, 182 unsigned int *count) 183{ 184 struct kinfo_proc *p0, *p; 185 size_t len; 186 int name[4]; 187 int cnt; --- 38 unchanged lines hidden (view full) --- 226 } 227 error = sysctl(name, 4, p, &len, NULL, 0); 228 if (error < 0 && errno != EPERM) { 229 warn("sysctl(kern.proc)"); 230 goto fail; 231 } 232 /* Perform simple consistency checks. */ 233 if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) { | 205struct kinfo_proc * 206procstat_getprocs(struct procstat *procstat, int what, int arg, 207 unsigned int *count) 208{ 209 struct kinfo_proc *p0, *p; 210 size_t len; 211 int name[4]; 212 int cnt; --- 38 unchanged lines hidden (view full) --- 251 } 252 error = sysctl(name, 4, p, &len, NULL, 0); 253 if (error < 0 && errno != EPERM) { 254 warn("sysctl(kern.proc)"); 255 goto fail; 256 } 257 /* Perform simple consistency checks. */ 258 if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) { |
259 warnx("kinfo_proc structure size mismatch (len = %zu)", len); 260 goto fail; 261 } 262 *count = len / sizeof(*p); 263 return (p); 264 } else if (procstat->type == PROCSTAT_CORE) { 265 p = procstat_core_get(procstat->core, PSC_TYPE_PROC, NULL, 266 &len); 267 if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) { |
|
234 warnx("kinfo_proc structure size mismatch"); 235 goto fail; 236 } 237 *count = len / sizeof(*p); 238 return (p); 239 } else { 240 warnx("unknown access method: %d", procstat->type); 241 return (NULL); --- 11 unchanged lines hidden (view full) --- 253 if (p != NULL) 254 free(p); 255 p = NULL; 256} 257 258struct filestat_list * 259procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) 260{ | 268 warnx("kinfo_proc structure size mismatch"); 269 goto fail; 270 } 271 *count = len / sizeof(*p); 272 return (p); 273 } else { 274 warnx("unknown access method: %d", procstat->type); 275 return (NULL); --- 11 unchanged lines hidden (view full) --- 287 if (p != NULL) 288 free(p); 289 p = NULL; 290} 291 292struct filestat_list * 293procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) 294{ |
261 262 if (procstat->type == PROCSTAT_SYSCTL) 263 return (procstat_getfiles_sysctl(procstat, kp, mmapped)); 264 else if (procstat->type == PROCSTAT_KVM) | 295 296 switch(procstat->type) { 297 case PROCSTAT_KVM: |
265 return (procstat_getfiles_kvm(procstat, kp, mmapped)); | 298 return (procstat_getfiles_kvm(procstat, kp, mmapped)); |
266 else | 299 case PROCSTAT_SYSCTL: 300 case PROCSTAT_CORE: 301 return (procstat_getfiles_sysctl(procstat, kp, mmapped)); 302 default: 303 warnx("unknown access method: %d", procstat->type); |
267 return (NULL); | 304 return (NULL); |
305 } |
|
268} 269 270void 271procstat_freefiles(struct procstat *procstat, struct filestat_list *head) 272{ 273 struct filestat *fst, *tmp; 274 275 STAILQ_FOREACH_SAFE(fst, head, next, tmp) { --- 365 unchanged lines hidden (view full) --- 641 case KF_FD_TYPE_TRACE: 642 return (PS_FST_UFLAG_TRACE); 643 case KF_FD_TYPE_ROOT: 644 return (PS_FST_UFLAG_RDIR); 645 } 646 return (0); 647} 648 | 306} 307 308void 309procstat_freefiles(struct procstat *procstat, struct filestat_list *head) 310{ 311 struct filestat *fst, *tmp; 312 313 STAILQ_FOREACH_SAFE(fst, head, next, tmp) { --- 365 unchanged lines hidden (view full) --- 679 case KF_FD_TYPE_TRACE: 680 return (PS_FST_UFLAG_TRACE); 681 case KF_FD_TYPE_ROOT: 682 return (PS_FST_UFLAG_RDIR); 683 } 684 return (0); 685} 686 |
687static struct kinfo_file * 688kinfo_getfile_core(struct procstat_core *core, int *cntp) 689{ 690 int cnt; 691 size_t len; 692 char *buf, *bp, *eb; 693 struct kinfo_file *kif, *kp, *kf; 694 695 buf = procstat_core_get(core, PSC_TYPE_FILES, NULL, &len); 696 if (buf == NULL) 697 return (NULL); 698 /* 699 * XXXMG: The code below is just copy&past from libutil. 700 * The code duplication can be avoided if libutil 701 * is extended to provide something like: 702 * struct kinfo_file *kinfo_getfile_from_buf(const char *buf, 703 * size_t len, int *cntp); 704 */ 705 706 /* Pass 1: count items */ 707 cnt = 0; 708 bp = buf; 709 eb = buf + len; 710 while (bp < eb) { 711 kf = (struct kinfo_file *)(uintptr_t)bp; 712 bp += kf->kf_structsize; 713 cnt++; 714 } 715 716 kif = calloc(cnt, sizeof(*kif)); 717 if (kif == NULL) { 718 free(buf); 719 return (NULL); 720 } 721 bp = buf; 722 eb = buf + len; 723 kp = kif; 724 /* Pass 2: unpack */ 725 while (bp < eb) { 726 kf = (struct kinfo_file *)(uintptr_t)bp; 727 /* Copy/expand into pre-zeroed buffer */ 728 memcpy(kp, kf, kf->kf_structsize); 729 /* Advance to next packed record */ 730 bp += kf->kf_structsize; 731 /* Set field size to fixed length, advance */ 732 kp->kf_structsize = sizeof(*kp); 733 kp++; 734 } 735 free(buf); 736 *cntp = cnt; 737 return (kif); /* Caller must free() return value */ 738} 739 |
|
649static struct filestat_list * | 740static struct filestat_list * |
650procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) | 741procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, 742 int mmapped) |
651{ 652 struct kinfo_file *kif, *files; 653 struct kinfo_vmentry *kve, *vmentries; 654 struct filestat_list *head; 655 struct filestat *entry; 656 char *path; 657 off_t offset; 658 int cnt, fd, fflags; 659 int i, type, uflags; 660 int refcount; 661 cap_rights_t cap_rights; 662 663 assert(kp); 664 if (kp->ki_fd == NULL) 665 return (NULL); | 743{ 744 struct kinfo_file *kif, *files; 745 struct kinfo_vmentry *kve, *vmentries; 746 struct filestat_list *head; 747 struct filestat *entry; 748 char *path; 749 off_t offset; 750 int cnt, fd, fflags; 751 int i, type, uflags; 752 int refcount; 753 cap_rights_t cap_rights; 754 755 assert(kp); 756 if (kp->ki_fd == NULL) 757 return (NULL); |
666 667 files = kinfo_getfile(kp->ki_pid, &cnt); | 758 switch(procstat->type) { 759 case PROCSTAT_SYSCTL: 760 files = kinfo_getfile(kp->ki_pid, &cnt); 761 break; 762 case PROCSTAT_CORE: 763 files = kinfo_getfile_core(procstat->core, &cnt); 764 break; 765 default: 766 assert(!"invalid type"); 767 } |
668 if (files == NULL && errno != EPERM) { 669 warn("kinfo_getfile()"); 670 return (NULL); 671 } 672 procstat->files = files; 673 674 /* 675 * Allocate list head. --- 61 unchanged lines hidden (view full) --- 737procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst, 738 struct pipestat *ps, char *errbuf) 739{ 740 741 assert(ps); 742 if (procstat->type == PROCSTAT_KVM) { 743 return (procstat_get_pipe_info_kvm(procstat->kd, fst, ps, 744 errbuf)); | 768 if (files == NULL && errno != EPERM) { 769 warn("kinfo_getfile()"); 770 return (NULL); 771 } 772 procstat->files = files; 773 774 /* 775 * Allocate list head. --- 61 unchanged lines hidden (view full) --- 837procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst, 838 struct pipestat *ps, char *errbuf) 839{ 840 841 assert(ps); 842 if (procstat->type == PROCSTAT_KVM) { 843 return (procstat_get_pipe_info_kvm(procstat->kd, fst, ps, 844 errbuf)); |
745 } else if (procstat->type == PROCSTAT_SYSCTL) { | 845 } else if (procstat->type == PROCSTAT_SYSCTL || 846 procstat->type == PROCSTAT_CORE) { |
746 return (procstat_get_pipe_info_sysctl(fst, ps, errbuf)); 747 } else { 748 warnx("unknown access method: %d", procstat->type); 749 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 750 return (1); 751 } 752} 753 --- 47 unchanged lines hidden (view full) --- 801procstat_get_pts_info(struct procstat *procstat, struct filestat *fst, 802 struct ptsstat *pts, char *errbuf) 803{ 804 805 assert(pts); 806 if (procstat->type == PROCSTAT_KVM) { 807 return (procstat_get_pts_info_kvm(procstat->kd, fst, pts, 808 errbuf)); | 847 return (procstat_get_pipe_info_sysctl(fst, ps, errbuf)); 848 } else { 849 warnx("unknown access method: %d", procstat->type); 850 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 851 return (1); 852 } 853} 854 --- 47 unchanged lines hidden (view full) --- 902procstat_get_pts_info(struct procstat *procstat, struct filestat *fst, 903 struct ptsstat *pts, char *errbuf) 904{ 905 906 assert(pts); 907 if (procstat->type == PROCSTAT_KVM) { 908 return (procstat_get_pts_info_kvm(procstat->kd, fst, pts, 909 errbuf)); |
809 } else if (procstat->type == PROCSTAT_SYSCTL) { | 910 } else if (procstat->type == PROCSTAT_SYSCTL || 911 procstat->type == PROCSTAT_CORE) { |
810 return (procstat_get_pts_info_sysctl(fst, pts, errbuf)); 811 } else { 812 warnx("unknown access method: %d", procstat->type); 813 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 814 return (1); 815 } 816} 817 --- 45 unchanged lines hidden (view full) --- 863procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, 864 struct shmstat *shm, char *errbuf) 865{ 866 867 assert(shm); 868 if (procstat->type == PROCSTAT_KVM) { 869 return (procstat_get_shm_info_kvm(procstat->kd, fst, shm, 870 errbuf)); | 912 return (procstat_get_pts_info_sysctl(fst, pts, errbuf)); 913 } else { 914 warnx("unknown access method: %d", procstat->type); 915 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 916 return (1); 917 } 918} 919 --- 45 unchanged lines hidden (view full) --- 965procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, 966 struct shmstat *shm, char *errbuf) 967{ 968 969 assert(shm); 970 if (procstat->type == PROCSTAT_KVM) { 971 return (procstat_get_shm_info_kvm(procstat->kd, fst, shm, 972 errbuf)); |
871 } else if (procstat->type == PROCSTAT_SYSCTL) { | 973 } else if (procstat->type == PROCSTAT_SYSCTL || 974 procstat->type == PROCSTAT_CORE) { |
872 return (procstat_get_shm_info_sysctl(fst, shm, errbuf)); 873 } else { 874 warnx("unknown access method: %d", procstat->type); 875 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 876 return (1); 877 } 878} 879 --- 63 unchanged lines hidden (view full) --- 943procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, 944 struct vnstat *vn, char *errbuf) 945{ 946 947 assert(vn); 948 if (procstat->type == PROCSTAT_KVM) { 949 return (procstat_get_vnode_info_kvm(procstat->kd, fst, vn, 950 errbuf)); | 975 return (procstat_get_shm_info_sysctl(fst, shm, errbuf)); 976 } else { 977 warnx("unknown access method: %d", procstat->type); 978 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 979 return (1); 980 } 981} 982 --- 63 unchanged lines hidden (view full) --- 1046procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, 1047 struct vnstat *vn, char *errbuf) 1048{ 1049 1050 assert(vn); 1051 if (procstat->type == PROCSTAT_KVM) { 1052 return (procstat_get_vnode_info_kvm(procstat->kd, fst, vn, 1053 errbuf)); |
951 } else if (procstat->type == PROCSTAT_SYSCTL) { | 1054 } else if (procstat->type == PROCSTAT_SYSCTL || 1055 procstat->type == PROCSTAT_CORE) { |
952 return (procstat_get_vnode_info_sysctl(fst, vn, errbuf)); 953 } else { 954 warnx("unknown access method: %d", procstat->type); 955 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 956 return (1); 957 } 958} 959 --- 185 unchanged lines hidden (view full) --- 1145procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, 1146 struct sockstat *sock, char *errbuf) 1147{ 1148 1149 assert(sock); 1150 if (procstat->type == PROCSTAT_KVM) { 1151 return (procstat_get_socket_info_kvm(procstat->kd, fst, sock, 1152 errbuf)); | 1056 return (procstat_get_vnode_info_sysctl(fst, vn, errbuf)); 1057 } else { 1058 warnx("unknown access method: %d", procstat->type); 1059 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1060 return (1); 1061 } 1062} 1063 --- 185 unchanged lines hidden (view full) --- 1249procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, 1250 struct sockstat *sock, char *errbuf) 1251{ 1252 1253 assert(sock); 1254 if (procstat->type == PROCSTAT_KVM) { 1255 return (procstat_get_socket_info_kvm(procstat->kd, fst, sock, 1256 errbuf)); |
1153 } else if (procstat->type == PROCSTAT_SYSCTL) { | 1257 } else if (procstat->type == PROCSTAT_SYSCTL || 1258 procstat->type == PROCSTAT_CORE) { |
1154 return (procstat_get_socket_info_sysctl(fst, sock, errbuf)); 1155 } else { 1156 warnx("unknown access method: %d", procstat->type); 1157 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1158 return (1); 1159 } 1160} 1161 --- 234 unchanged lines hidden (view full) --- 1396 err(1, NULL); 1397 mt->m = m; 1398 bcopy(&mnt.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN); 1399 mt->mntonname[MNAMELEN] = '\0'; 1400 mt->next = mhead; 1401 mhead = mt; 1402 return (mt->mntonname); 1403} | 1259 return (procstat_get_socket_info_sysctl(fst, sock, errbuf)); 1260 } else { 1261 warnx("unknown access method: %d", procstat->type); 1262 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1263 return (1); 1264 } 1265} 1266 --- 234 unchanged lines hidden (view full) --- 1501 err(1, NULL); 1502 mt->m = m; 1503 bcopy(&mnt.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN); 1504 mt->mntonname[MNAMELEN] = '\0'; 1505 mt->next = mhead; 1506 mhead = mt; 1507 return (mt->mntonname); 1508} |
1509 |
|