Date: Sat, 18 Sep 2010 11:28:00 +0200 From: Norberto Lopes <nlopes.ml@gmail.com> To: Kostik Belousov <kostikbel@gmail.com> Cc: freebsd-current@freebsd.org, netchild@freebsd.org Subject: Re: Extend ktrace/kdump output Message-ID: <AANLkTimCwNA2BGbm9N-iFo%2BomR06h%2BXJDxOFSrT0AnJ7@mail.gmail.com> In-Reply-To: <AANLkTikWEzjeA8miRXkkSBuK65sBi%2BtDvx7F=mirTZ7g@mail.gmail.com> References: <8C5C36F5-A070-4CBA-8B8C-6751F8D636E1@gmail.com> <20100917203645.GS2389@deviant.kiev.zoral.com.ua> <AANLkTikWEzjeA8miRXkkSBuK65sBi%2BtDvx7F=mirTZ7g@mail.gmail.com>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --] Anyway, attached is the patch. All (constructive) criticism is welcome, even if it has to deal with "how I should do things freebsd way (in case there is one)". On Fri, Sep 17, 2010 at 10:48 PM, Norberto Lopes <nlopes.ml@gmail.com> wrote: > On Fri, Sep 17, 2010 at 10:36 PM, Kostik Belousov <kostikbel@gmail.com> wrote: >> On Fri, Sep 17, 2010 at 09:55:26PM +0200, Norberto Lopes wrote: >>> Hi. >>> I've been taking a look at ktrace and kdump in order to get (1) familiar with the sources and (2) to finally try to give back something to the community. >>> >>> So far from what I've seen, and after reading this thread http://lists.freebsd.org/pipermail/freebsd-arch/2006-April/005107.html it seems that most of those points got done. >>> >>> To warm up I changed the output of the stat structure in order to provide me with the device name (something I actually find useful for me sometimes) >>> >>> Instead of: >>> 22596 cat STRU struct stat {dev=89, ino=3320836, mode=-r--r--r-- , nlink=1, uid=0, gid=0, atime=1284725358, stime=1284485510, ctime=1284485510, birthtime=1284485509, size=1172220, blksize=16384, blocks=2336, flags=0x20000 } >>> >>> I get this now (including major and minor): >>> 22596 cat STRU struct stat {dev=<id=89:M=0:m=89> (/dev/ad4s1a), ino=3320836, mode=-r--r--r-- , nlink=1, uid=0, gid=0, atime=1284725358, stime=1284485510, ctime=1284485510, birthtime=1284485509, size=1172220, blksize=16384, blocks=2336, flags=0x20000 } >>> >>> I wouldn't mind having someone help me whenever and if I get stuck on the technical side (*wink* Alexander Leidinger *wink*) and also to give me more insight on what the road to help in this should be. >>> >>> P.S.: I'm still going through "man style" hence no patch attached. If anyone finds this one useful, I'll reply with the patch though. >>> >> How do you look up the device name by st_dev ? Note that the number is >> generated by devfs at the moment of cdev creation. It is only valid on >> the machine where stat(2) is done, and only due to the next reboot. >> > > Through a really ugly hack... > opendir("/dev") > readdir("/dev") > go through them and find the one... > > Yes, I know, painful and ugly, but as I usually use kdump with no > reboots between analysis (I hardly ever reboot actually), and because > I find it exhausting to keep going back to look up the device name, > this kept me happy enough. :) > [-- Attachment #2 --] Index: kdump.c =================================================================== --- kdump.c (revision 212820) +++ kdump.c (working copy) @@ -82,6 +82,8 @@ extern int errno; #include <time.h> #include <unistd.h> #include <vis.h> +#include <dirent.h> +#include <stdbool.h> #include "ktrace.h" #include "kdump_subr.h" @@ -1249,6 +1251,11 @@ ktrstat(struct stat *statp) struct passwd *pwd; struct group *grp; struct tm *tm; + DIR *od = NULL; + struct stat *dev_stat; + struct dirent *dev_entry; + char *dev_name, *dev_path="/dev/"; + bool found_dev = false; /* * note: ktrstruct() has already verified that statp points to a @@ -1256,9 +1263,73 @@ ktrstat(struct stat *statp) */ printf("struct stat {"); strmode(statp->st_mode, mode); - printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ", - (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode, - (uintmax_t)statp->st_nlink); + + dev_stat = (struct stat *)malloc(sizeof(struct stat)); + if (dev_stat == NULL) + errx(1, "%s", strerror(ENOMEM)); + + /* check if we can reach it and open it */ + if (!stat(dev_path, dev_stat) && (od = opendir(dev_path)) == NULL) + free(dev_stat); + else { + while ((dev_entry = readdir(od)) != NULL && found_dev == false) { + /* ignore "." and ".." */ + if ((strcmp(dev_entry->d_name, ".") == 0) || + (strcmp(dev_entry->d_name, "..") == 0)) + continue; + + dev_name = (char *)malloc(sizeof(char)* + (strlen(dev_path)+strlen(dev_entry->d_name))); + + if (dev_name == NULL) + errx(1, "%s", strerror(ENOMEM)); + + (void)sprintf(dev_name, "%s%s", dev_path, + dev_entry->d_name); + + dev_stat = (struct stat *)malloc(sizeof(struct stat)); + if (dev_stat == NULL) + errx(1, "%s", strerror(ENOMEM)); + + if (stat(dev_name, dev_stat) == -1) { + free(dev_stat); + continue; + } + + /* + * If the file device number equals the device inode + * we have the device that contains the file. + * + * In the chance that we find that the "file" inode + * equals the device inode, then they are the same too. + */ + if ((uintmax_t)statp->st_dev == + (uintmax_t)dev_stat->st_ino) { + found_dev = true; + break; + } + else if ((uintmax_t)statp->st_ino == + (uintmax_t)dev_stat->st_ino) { + found_dev = true; + break; + } + + free(dev_name); + free(dev_stat); + } + } + if (found_dev) { + printf("dev=<id=%ju:M=%d:m=%d> (%s),", + (uintmax_t)statp->st_dev, major(statp->st_dev), + minor(statp->st_dev), dev_name); + free(dev_name); + } + else + printf("dev=<id=%ju:M=%d:m=%d>,", (uintmax_t)statp->st_dev, + major(statp->st_dev), minor(statp->st_dev)); + + printf(" ino=%ju, mode=%s, nlink=%ju, ", + (uintmax_t)statp->st_ino, mode, (uintmax_t)statp->st_nlink); + if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) printf("uid=%ju, ", (uintmax_t)statp->st_uid); else @@ -1267,7 +1338,11 @@ ktrstat(struct stat *statp) printf("gid=%ju, ", (uintmax_t)statp->st_gid); else printf("gid=\"%s\", ", grp->gr_name); + + /* XXX: Do we really need rdev in case it's not character or block? */ + /* if (S_ISCHR(statp->st_mode) || S_ISBLK(statp->st_mode)) */ printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); + printf("atime="); if (resolv == 0) printf("%jd", (intmax_t)statp->st_atim.tv_sec); @@ -1317,8 +1392,8 @@ ktrstat(struct stat *statp) else printf(", "); printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", - (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, - (intmax_t)statp->st_blocks, statp->st_flags); + (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, + (intmax_t)statp->st_blocks, statp->st_flags); printf(" }\n"); }help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTimCwNA2BGbm9N-iFo%2BomR06h%2BXJDxOFSrT0AnJ7>
