The md ioctls expect their extra arguments to be unsigned longs (explicitly converted to kdev_t), while raidtools-0.50beta2 provides ints and dev_ts. As these arguments are covered by an ellipsis in the C prototype, no conversion is done by the compiler. Usually it works out O.K. on little-endian machines. Sun Sparcs are big-endian. Trying to add /dev/sdc1 to /dev/md0 fails with the following syslog message: md_add(): zero device size, huh, bailing out. The strace log ended with: ... stat("/dev/sdc1", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 33), ...}) = 0 ioctl(5, REGISTER_DEV, 0) = -1 EINVAL (Invalid argument) write(2, "/dev/sdc1: Invalid argument\n", 28) = 28 exit(0) = ? The relevant source fragment in raidadd.c is: if (stat (dev, &s)) { ... } ... if (ioctl (fd, REGISTER_DEV, s.st_rdev)) { ... perror (dev); ... } The device /dev/sdc1 is stat()ed for its device number (8/33), which is sent as the ioctl()'s third argument (type dev_t). In the kernel (`drivers/block/md.c', md_ioctl()) the extra argument is read as were it a long, silently padded with (hopefully) zero bytes. With big-end numbers, this shifts the original short toward the long's MSBs. The subequent conversion to a kdev_t is done by examining the long's LSBs, where the zeros happen to be. So the kernel believes that I am trying to add the 0/0 device to /dev/md0, and rightly rejects my request. Also, gcc had gripes about redefining __NR__llseek, an really bad thing to do, espesially as <asm/unistd.h> defines it to 236, not 140. After adding the patch below, raidtools compiled and ran with no trouble. I am running Linux 2.2.0-pre8smp, by the way. /Sverker ====================== diff -u orig/raidtools-0.50/raid_io.c raidtools-0.50/raid_io.c --- orig/raidtools-0.50/raid_io.c Thu Jul 23 23:32:25 1998 +++ raidtools-0.50/raid_io.c Wed Jan 27 00:07:26 1999 @@ -78,7 +78,13 @@ } #undef F +#if !defined(__NR__llseek) +/* + * Architecture-specific syscall number. Use the one in + * <asm/unistd.h> instead. + */ #define __NR__llseek 140 +#endif static int _llseek (unsigned int, unsigned long, unsigned long, long long *, unsigned int); @@ -284,7 +290,7 @@ fprintf(stderr, "couldn't open device %s -- %s\n", cfg-> device_name[i], strerror(errno)); return 1; } - if (ioctl(fd, BLKGETSIZE, &nr_blocks) == -1) { + if (ioctl(fd, BLKGETSIZE, (unsigned long)&nr_blocks) == -1) { fprintf(stderr, "couldn't get device size for %s -- %s\n ", cfg->device_name[i], strerror(errno)); close(fd); return 1; diff -u orig/raidtools-0.50/raidadd.c raidtools-0.50/raidadd.c --- orig/raidtools-0.50/raidadd.c Thu Jul 23 23:32:26 1998 +++ raidtools-0.50/raidadd.c Wed Jan 27 05:30:57 1999 @@ -89,7 +89,7 @@ save_errno=EPERM; /* used in case of valid return */ } - if (ioctl (fd, REGISTER_DEV, s.st_rdev)) { + if (ioctl (fd, REGISTER_DEV, (unsigned long)s.st_rdev)) { save_errno = errno; perror (dev); errno=save_errno; @@ -101,7 +101,7 @@ static int do_mdstart (int fd, char *dev, int pers) { - if (ioctl (fd, START_MD, pers)) { + if (ioctl (fd, START_MD, (unsigned long)pers)) { save_errno=errno; perror (dev); errno=save_errno; @@ -112,7 +112,7 @@ static int do_mdstop (int fd, char *dev) { - if (ioctl (fd, STOP_MD, 0)) { + if (ioctl (fd, STOP_MD, 0UL)) { save_errno=errno; perror (dev); errno=save_errno;