Index: kdump.c =================================================================== --- kdump.c (revision 212820) +++ kdump.c (working copy) @@ -82,6 +82,8 @@ extern int errno; #include #include #include +#include +#include #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= (%s),", + (uintmax_t)statp->st_dev, major(statp->st_dev), + minor(statp->st_dev), dev_name); + free(dev_name); + } + else + printf("dev=,", (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"); }