Re: disk_map in subr_disk.c
On Wed, Jul 25, 2012 at 11:37:32PM +0200, Frank Brodbeck wrote: On Wed, Jul 25, 2012 at 10:51:56PM +0200, Otto Moerbeek wrote: Userland prorams do not share memory or symbols with the kernel at all that is a fundamental thing in Unix. Your code just references a bunch of uninitialized vars. Chekc opendev(3) (source in src/lib/libutil/opendev.c) which is a userland function to do the translation you want. Note it interfaces with the kernel via ioctl(2), the actual work is done by the diskmap device driver that calls disk_map(), all in kernel mode. Funny, I first looked at opendev(3) and the DIOCMAP ioctl before I went on to disk_map(). Obviously I missed something. Will have a look at opendev(3) again. Thanks a lot for the pointer. Frank. Maybe this helps: #include sys/types.h #include sys/dkio.h #include sys/disk.h #include sys/ioctl.h #include err.h #include fcntl.h #include limits.h #include stdio.h #include stdlib.h #include string.h #include unistd.h int main(int argc, char *argv[]) { struct dk_diskmap dm; const char *dmpath = /dev/diskmap; char dev[PATH_MAX]; char *d; if (argc != 2) { fprintf(stderr, usage: duid2dev duid|device\n); exit(1); } bzero(dm, sizeof(dm)); dm.flags = DM_OPENPART; if ((dm.fd = open(dmpath, O_RDONLY)) 0) err(1, open: %s, dmpath); strlcpy(dev, argv[1], PATH_MAX); dm.device = dev; if (ioctl(dm.fd, DIOCMAP, dm) == -1) err(1, ioctl); d = strrchr(dm.device, '/'); if (d[1] == 'r') dm.device = d + 2; else dm.device = d + 1; dm.device[strlen(dm.device) - 1] = '\0'; printf(%s\n, dm.device); close(dm.fd); exit(0); } -- Frank Brodbeck f...@guug.de
Re: disk_map in subr_disk.c
On Wed, Jul 25, 2012 at 09:34:02PM +0200, Frank Brodbeck wrote: | Hi, | | currently I am trying (just out of curiosity) to find a way to resolve a | duid to a device name. For that matter I believe that looking at | disk_map() in subr_disk.c is the right place. Or try sysctl(3). Here's some output from sysctl(8): hw.disknames=sd0:3e482244f831fa23,cd0: Paul 'WEiRD' de Weerd -- [++-]+++.+++[---].+++[+ +++-].++[-]+.--.[-] http://www.weirdnet.nl/
disk_map in subr_disk.c
Hi, currently I am trying (just out of curiosity) to find a way to resolve a duid to a device name. For that matter I believe that looking at disk_map() in subr_disk.c is the right place. As I am a complete C beginner I have a hard time to understand a particular block of code so I decided to copy that function into my own C code so I can easily track what's going on w/ gdb: int main(void) { struct disk *dk, *mdk; struct disklist_head disklist; u_char uid[8]; char *path, *mpath, part, c; int i; path = 9c750dc043a2751f.i; part = path[17]; bzero(uid, sizeof(uid)); for (i = 0; i 16; i++) { c = path[i]; if (c = '0' c = '9') c -= '0'; else if (c = 'a' c = 'f') c -= ('a' - 10); else errx(Invalid duid); uid[i / 2] = 4; uid[i / 2] |= c 0xf; } mdk = NULL; TAILQ_FOREACH(dk, disklist, dk_link) { if ((dk-dk_flags DKF_LABELVALID) dk-dk_label bcmp(dk-dk_label-d_uid, uid, sizeof(dk-dk_label-d_uid)) == 0) { if (mdk != NULL) return -1; mdk = dk; } } return 0; } If I run the program I get a segfault and w/ gdb I see: Program received signal SIGSEGV, Segmentation fault. bcmp (b1=0x1c7f88988, b2=0x7f7be830, length=8) at /usr/src/lib/libc/string/bcmp.c:51 Which I believe is caused by dk-dk_label-d_uid being inaccessible: (gdb) print dk-dk_label $1 = (struct disklabel *) 0x1c7f88948 (gdb) print dk-dk_label-d_uid Cannot access memory at address 0x1c7f88988 In dev/diskmap.c I see copyinstr(9) before disk_map() and copyoutstr(9) after disk_map. Is this because dk-dk_label-d_uid is not accessible from userspace or am I talking complete BS here? Beatings with the cluestick are welcomed. Thanks, Frank. -- Frank Brodbeck f...@guug.de
Re: disk_map in subr_disk.c
On Wed, Jul 25, 2012 at 09:34:02PM +0200, Frank Brodbeck wrote: Hi, currently I am trying (just out of curiosity) to find a way to resolve a duid to a device name. For that matter I believe that looking at disk_map() in subr_disk.c is the right place. As I am a complete C beginner I have a hard time to understand a particular block of code so I decided to copy that function into my own C code so I can easily track what's going on w/ gdb: int main(void) { struct disk *dk, *mdk; struct disklist_head disklist; u_char uid[8]; char *path, *mpath, part, c; int i; path = 9c750dc043a2751f.i; part = path[17]; bzero(uid, sizeof(uid)); for (i = 0; i 16; i++) { c = path[i]; if (c = '0' c = '9') c -= '0'; else if (c = 'a' c = 'f') c -= ('a' - 10); else errx(Invalid duid); uid[i / 2] = 4; uid[i / 2] |= c 0xf; } mdk = NULL; TAILQ_FOREACH(dk, disklist, dk_link) { if ((dk-dk_flags DKF_LABELVALID) dk-dk_label bcmp(dk-dk_label-d_uid, uid, sizeof(dk-dk_label-d_uid)) == 0) { if (mdk != NULL) return -1; mdk = dk; } } return 0; } If I run the program I get a segfault and w/ gdb I see: Program received signal SIGSEGV, Segmentation fault. bcmp (b1=0x1c7f88988, b2=0x7f7be830, length=8) at /usr/src/lib/libc/string/bcmp.c:51 Which I believe is caused by dk-dk_label-d_uid being inaccessible: (gdb) print dk-dk_label $1 = (struct disklabel *) 0x1c7f88948 (gdb) print dk-dk_label-d_uid Cannot access memory at address 0x1c7f88988 In dev/diskmap.c I see copyinstr(9) before disk_map() and copyoutstr(9) after disk_map. Is this because dk-dk_label-d_uid is not accessible from userspace or am I talking complete BS here? Userland prorams do not share memory or symbols with the kernel at all that is a fundamental thing in Unix. Your code just references a bunch of uninitialized vars. Chekc opendev(3) (source in src/lib/libutil/opendev.c) which is a userland function to do the translation you want. Note it interfaces with the kernel via ioctl(2), the actual work is done by the diskmap device driver that calls disk_map(), all in kernel mode. -Otto
Re: disk_map in subr_disk.c
On Wed, Jul 25, 2012 at 10:51:56PM +0200, Otto Moerbeek wrote: Userland prorams do not share memory or symbols with the kernel at all that is a fundamental thing in Unix. Your code just references a bunch of uninitialized vars. Chekc opendev(3) (source in src/lib/libutil/opendev.c) which is a userland function to do the translation you want. Note it interfaces with the kernel via ioctl(2), the actual work is done by the diskmap device driver that calls disk_map(), all in kernel mode. Funny, I first looked at opendev(3) and the DIOCMAP ioctl before I went on to disk_map(). Obviously I missed something. Will have a look at opendev(3) again. Thanks a lot for the pointer. Frank. -- Frank Brodbeck f...@guug.de