Re: disk_map in subr_disk.c

2012-07-27 Thread Tobias Ulmer
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

2012-07-26 Thread Paul de Weerd
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

2012-07-25 Thread Frank Brodbeck
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

2012-07-25 Thread Otto Moerbeek
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

2012-07-25 Thread Frank Brodbeck
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