Your message dated Fri, 25 Mar 2005 11:04:12 -0500
with message-id <[EMAIL PROTECTED]>
and subject line Bug#298606: fixed in quik 2.1-5
has caused the attached Bug report to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere. Please contact me immediately.)
Debian bug tracking system administrator
(administrator, Debian Bugs database)
--------------------------------------
Received: (at submit) by bugs.debian.org; 8 Mar 2005 20:03:35 +0000
>From [EMAIL PROTECTED] Tue Mar 08 12:03:34 2005
Return-path: <[EMAIL PROTECTED]>
Received: from rproxy.gmail.com [64.233.170.196]
by spohr.debian.org with esmtp (Exim 3.35 1 (Debian))
id 1D8kvW-0001Xg-00; Tue, 08 Mar 2005 12:03:34 -0800
Received: by rproxy.gmail.com with SMTP id i8so1374964rne
for <[EMAIL PROTECTED]>; Tue, 08 Mar 2005 12:03:34 -0800 (PST)
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=beta; d=gmail.com;
h=received:date:from:to:subject:message-id:x-mailer:mime-version:content-type:content-transfer-encoding;
b=kURiluvullF0baM097X6FSt5n2Q7M5R+HmKmPeNn98nA/vyRQIEQQcy/5dDBun/3txxMpEDXLOyxtNec7B6FJCfmPF1Z3ECYSbzyPWGl84pz+dzLbUZiDtXH6Pi/yUlvWfSumCuPa3GqJH7nfBvOMAKVccST6qgqfOizRDstV0I=
Received: by 10.38.82.76 with SMTP id f76mr101068rnb;
Tue, 08 Mar 2005 12:03:33 -0800 (PST)
Received: from tertius.castalie.org ([213.41.173.122])
by smtp.gmail.com with ESMTP id 73sm679913rna.2005.03.08.12.03.32;
Tue, 08 Mar 2005 12:03:33 -0800 (PST)
Date: Tue, 8 Mar 2005 21:03:29 +0100
From: Simon Vallet <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED],
Subject: quik does not support md devices
Message-ID: <[EMAIL PROTECTED]>
X-Mailer: Sylpheed-Claws 0.9.12b (GTK+ 1.2.10; powerpc-unknown-linux-gnu)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Delivered-To: [EMAIL PROTECTED]
X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2005_01_02
(1.212-2003-09-23-exp) on spohr.debian.org
X-Spam-Status: No, hits=-8.0 required=4.0 tests=BAYES_00,HAS_PACKAGE
autolearn=no version=2.60-bugs.debian.org_2005_01_02
X-Spam-Level:
Package: quik
Version: 2.1-4
Severity: normal
Tags: patch
quik does not support linux metadevices (/dev/md). This is filed as a
normal bug as quik does not recognize an md device, and incorrectly
tries to find partitions on it.
The included patch fixes the problem by adding limited md support to
quik -- the included README.md lists the current limitations. It was
generated against the 2.1-4 version from sid.
diff -Naur quik.orig/include/linux/raid/md_u.h quik/include/linux/raid/md_u.h
--- quik.orig/include/linux/raid/md_u.h 1970-01-01 01:00:00.000000000 +0100
+++ quik/include/linux/raid/md_u.h 2005-02-28 20:21:13.000000000 +0100
@@ -0,0 +1,116 @@
+/*
+ md_u.h : user <=> kernel API between Linux raidtools and RAID drivers
+ Copyright (C) 1998 Ingo Molnar
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ You should have received a copy of the GNU General Public License
+ (for example /usr/src/linux/COPYING); if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _MD_U_H
+#define _MD_U_H
+
+/* ioctls */
+
+/* status */
+#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t)
+#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t)
+#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
+#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13)
+#define RAID_AUTORUN _IO (MD_MAJOR, 0x14)
+
+/* configuration */
+#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20)
+#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t)
+#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22)
+#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t)
+#define SET_DISK_INFO _IO (MD_MAJOR, 0x24)
+#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25)
+#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26)
+#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27)
+#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28)
+#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29)
+
+/* usage */
+#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t)
+#define START_ARRAY _IO (MD_MAJOR, 0x31)
+#define STOP_ARRAY _IO (MD_MAJOR, 0x32)
+#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33)
+#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34)
+
+typedef struct mdu_version_s {
+ int major;
+ int minor;
+ int patchlevel;
+} mdu_version_t;
+
+typedef struct mdu_array_info_s {
+ /*
+ * Generic constant information
+ */
+ int major_version;
+ int minor_version;
+ int patch_version;
+ int ctime;
+ int level;
+ int size;
+ int nr_disks;
+ int raid_disks;
+ int md_minor;
+ int not_persistent;
+
+ /*
+ * Generic state information
+ */
+ int utime; /* 0 Superblock update time */
+ int state; /* 1 State bits (clean, ...) */
+ int active_disks; /* 2 Number of currently active disks */
+ int working_disks; /* 3 Number of working disks */
+ int failed_disks; /* 4 Number of failed disks */
+ int spare_disks; /* 5 Number of spare disks */
+
+ /*
+ * Personality information
+ */
+ int layout; /* 0 the array's physical layout */
+ int chunk_size; /* 1 chunk size in bytes */
+
+} mdu_array_info_t;
+
+typedef struct mdu_disk_info_s {
+ /*
+ * configuration/status of one particular disk
+ */
+ int number;
+ int major;
+ int minor;
+ int raid_disk;
+ int state;
+
+} mdu_disk_info_t;
+
+typedef struct mdu_start_info_s {
+ /*
+ * configuration/status of one particular disk
+ */
+ int major;
+ int minor;
+ int raid_disk;
+ int state;
+
+} mdu_start_info_t;
+
+typedef struct mdu_param_s
+{
+ int personality; /* 1,2,3,4 */
+ int chunk_size; /* in bytes */
+ int max_fault; /* unused for now */
+} mdu_param_t;
+
+#endif
+
diff -Naur quik.orig/include/quik_md.h quik/include/quik_md.h
--- quik.orig/include/quik_md.h 1970-01-01 01:00:00.000000000 +0100
+++ quik/include/quik_md.h 2005-03-03 20:44:31.000000000 +0100
@@ -0,0 +1,101 @@
+/*
+ * quik-md.h - definitions for md handling in quik
+ *
+ * Copyright (C) 2005 Simon Vallet <[EMAIL PROTECTED]>
+ *
+ * Information retrieval code for md devices is derived from
+ * Detail.c in mdadm version 1.9.0, and therefore:
+ *
+ * Copyright (C) 2001-2002 Neil Brown <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _QUIKMD_H
+#define _QUIKMD_H
+
+#define __u32 u_int32_t
+#define __u64 u_int64_t
+
+#define MD_MAJOR 9
+#define DEV_BUFSZ 1024
+
+#define u32 u_int32_t
+#define u8 u_int8_t
+
+#include <sys/ioctl.h>
+#include <asm/ioctl.h>
+
+/* From md_p.h */
+#define MD_SB_DISKS 27
+#include <linux/raid/md_u.h>
+
+struct devmap {
+ int major, minor;
+ char *name;
+ struct devmap *next;
+};
+
+typedef struct mapping {
+ char *name;
+ int num;
+} mapping_t;
+
+#define __USE_XOPEN_EXTENDED
+#include <ftw.h>
+
+char *map_num(mapping_t *, int);
+char *map_dev(int, int);
+int is_standard(char *, int *);
+int add_dev(const char *, const struct stat *, int, struct FTW *);
+int digit_offset (const char *);
+
+//void fatal (const char *);
+
+typedef struct dev_info {
+ char * bootdev; /* Physical device, e.g. /dev/hda */
+ char * spart; /* Filesystem device for second.b, e.g. /dev/hda2 */
+ int cpart; /* Conffile part. number */
+ int part_block; /* Block # of partition map entry */
+ int secsize; /* Disk sector size */
+ int first_bootable; /* Part. map entry # of 1st bootable part */
+ unsigned long doff; /* Start of part. containing second.b */
+ struct first_info finfo; /* Boot block structure */
+} dev_info_t;
+
+typedef struct mdev_info {
+ char * metadev; /* Metadevice, e.g. /dev/md0, if necessary */
+ char * fs_dev; /* Device containing the filesystem */
+ dev_info_t ** devs;
+ unsigned int bs;
+ unsigned int nsect;
+ unsigned char ndevs;
+ int rlevel;
+} mdev_info_t;
+
+#define BOOTDEV(dev,i) ((dev)->devs[(i)]->bootdev)
+#define SPART(dev,i) ((dev)->devs[(i)]->spart)
+
+dev_info_t * new_dev_info (unsigned char);
+void free_dev_info (dev_info_t *);
+int md_get_version (int);
+mdev_info_t * md_get_info (const char *);
+
+dev_info_t * new_dev_info ();
+void free_dev_info (dev_info_t *);
+mdev_info_t * new_mdev_info (unsigned char);
+void free_mdev_info (mdev_info_t *);
+
+#endif
diff -Naur quik.orig/quik/Makefile quik/quik/Makefile
--- quik.orig/quik/Makefile 2005-03-08 20:24:47.700579456 +0100
+++ quik/quik/Makefile 2005-03-08 20:32:22.918375832 +0100
@@ -1,10 +1,12 @@
-all: quik
+objects= quik_md.o quik.o
COPTS = -O -Wall
CFLAGS = -I../include $(COPTS)
-quik: quik.c
- $(CC) $(CFLAGS) -o quik quik.c
+all: quik
+
+quik: $(objects)
+ $(CC) $(CFLAGS) -o quik $(objects)
clean:
rm -f *.o *~ quik
diff -Naur quik.orig/quik/quik.c quik/quik/quik.c
--- quik.orig/quik/quik.c 2005-03-08 20:24:47.704578848 +0100
+++ quik/quik/quik.c 2005-03-08 20:44:29.577906000 +0100
@@ -2,6 +2,8 @@
Copyright (C) 1996 Paul Mackerras.
+ Copyright (C) 2005 Simon Vallet for the MD handling code
+
Derived from silo.c in the silo-0.6.4 distribution, therefore:
Copyright (C) 1996 Maurizio Plaza
@@ -33,12 +35,14 @@
#include <endian.h>
#include <fcntl.h>
#include <dirent.h>
-#include <layout.h>
#include <sys/ioctl.h>
-
#include <linux/fs.h>
#include <ext2fs/ext2_fs.h>
+
+#include <layout.h>
#include <asm/mac-part.h>
+#include <quik_md.h>
+
#define DFL_CONFIG "/etc/quik.conf"
#define ALT_CONFIG "/etc/milo.conf"
@@ -70,14 +74,7 @@
+ (((x) & 0xff00) << 8) + (((x) & 0xff) << 24))
#define swab_16(x) ((((x) >> 8) & 0xff) + (((x) & 0xff) << 8))
-unsigned nsect; /* # (512-byte) sectors per f.s. block
*/
-unsigned bs; /* f.s. block size */
-int part_block; /* block # of partition map entry */
-int secsize; /* disk sector size */
-int first_bootable; /* part map entry # of 1st bootable part */
-unsigned long doff; /* start of partition containing 2nd boot */
char *first, *second, *old; /* File names */
-struct first_info finfo;
int verbose;
void fatal(char *fmt,...) __attribute__ ((noreturn));
@@ -107,83 +104,106 @@
return -1;
}
-void read_sb(char *device, char *bootdev)
+int part_from_dev (char * spart)
{
- int fd, partno, part;
+ char * p = spart + strlen(spart);
+ while (p > spart && isdigit(p[-1]))
+ --p;
+ return atoi(p);
+}
+
+
+void read_sb (mdev_info_t * devs)
+{
+ int fd, partno, part, i;
int upart, maxpart;
struct mac_partition *mp;
struct mac_driver_desc *md;
- char *p;
char buff[512];
- if ((fd = open(device, O_RDONLY)) == -1)
- fatal("Cannot open %s", device);
- bs = check_fs(fd);
- if (bs == -1)
+ if ((fd = open(devs->fs_dev, O_RDONLY)) == -1)
+ fatal("Cannot open %s", devs->fs_dev);
+ devs->bs = check_fs(fd);
+ if (devs->bs == -1)
fatal("Filesystems other than ext2 are not supported");
close(fd);
- p = device + strlen(device);
- while (p > device && isdigit(p[-1]))
- --p;
- partno = atoi(p);
- if (partno == 0)
- fatal("Can't determine partition number for %s", device);
- upart = 0;
- mp = (struct mac_partition *) buff;
- md = (struct mac_driver_desc *) buff;
- if ((fd = open(bootdev, O_RDONLY)) == -1)
- fatal("Can't open %s", bootdev);
- if (read(fd, buff, sizeof (buff)) != sizeof (buff))
- fatal("Error reading %s (block 0)", bootdev);
- if (md->signature != MAC_DRIVER_MAGIC)
- fatal("%s is not a mac-formatted disk", bootdev);
- secsize = md->block_size;
- maxpart = 1;
- doff = 0;
- for (part = 1; part <= maxpart; ++part) {
- lseek(fd, part * secsize, 0);
+ for (i=0; i<devs->ndevs; i++) {
+ if (devs->devs[i]->bootdev) { /* Handle "missing" raid devices */
+ partno = part_from_dev(SPART(devs,i));
+ if (partno == 0)
+ fatal("Can't determine partition number for %s", SPART(devs,i));
+ upart = 0;
+ mp = (struct mac_partition *) buff;
+ md = (struct mac_driver_desc *) buff;
+ if ((fd = open(devs->devs[i]->bootdev, O_RDONLY)) == -1)
+ fatal("Can't open %s", BOOTDEV(devs, i));
if (read(fd, buff, sizeof (buff)) != sizeof (buff))
- fatal("Error reading partition map from %s", bootdev);
- if (mp->signature != MAC_PARTITION_MAGIC)
+ fatal("Error reading %s (block 0)", BOOTDEV(devs, i));
+ if (md->signature != MAC_DRIVER_MAGIC)
+ fatal("%s is not a mac-formatted disk", BOOTDEV(devs, i));
+
+ devs->devs[i]->secsize = md->block_size;
+ devs->devs[i]->doff = 0;
+ maxpart = 1;
+ for (part = 1; part <= maxpart; ++part) {
+ lseek(fd, part * devs->devs[i]->secsize, 0);
+
+ if (read(fd, buff, sizeof (buff)) != sizeof (buff))
+ fatal("Error reading partition map from %s", BOOTDEV(devs, i));
+ if (mp->signature != MAC_PARTITION_MAGIC)
break;
- if (part == 1)
+ if (part == 1)
maxpart = mp->map_count;
- else if (maxpart != mp->map_count)
+ else if (maxpart != mp->map_count)
break;
- if (first_bootable == 0 && (mp->status & STATUS_BOOTABLE) != 0
- && strcasecmp(mp->processor, "PowerPC") == 0)
- first_bootable = part;
- if (++upart == partno) {
+
+ if (devs->devs[i]->first_bootable == 0
+ && (mp->status & STATUS_BOOTABLE) != 0
+ && strcasecmp(mp->processor, "PowerPC") == 0)
+ devs->devs[i]->first_bootable = part;
+
+ if (++upart == partno) {
/* This is the one we want */
- part_block = part;
- doff = mp->start_block * (secsize >> 9);
+ devs->devs[i]->part_block = part;
+ devs->devs[i]->doff = mp->start_block * (devs->devs[i]->secsize >>
9);
break;
+ }
}
+ if (upart < partno)
+ fatal("Couldn't locate partition %d on %s", partno, BOOTDEV(devs, i));
+ }
}
- if (upart < partno)
- fatal("Couldn't locate partition %d on %s", partno, bootdev);
}
-void make_bootable(char *device, char *spart)
+void make_bootable (mdev_info_t * devs)
{
- int fd;
- struct mac_partition *mp;
- char buff[512];
+ int fd; int i;
+ struct mac_partition *mp;
+ char buff[512];
+ off_t seek_offset;
- if (part_block == 0)
- return;
+ for (i=0; i<devs->ndevs; i++) {
+ if (devs->devs[i]->part_block == 0)
+ return;
if (verbose)
- printf("Making %s bootable (map entry %d)\n", spart, part_block);
- if (first_bootable > 0 && first_bootable < part_block)
- fprintf(stderr, "Warning: prior partition (entry %d) is bootable\n",
- first_bootable);
- if ((fd = open(device, O_RDWR)) < 0)
- fatal("Cannot open %s for writing\n", device);
- lseek(fd, part_block * secsize, 0);
- if (read(fd, buff, sizeof(buff)) != sizeof(buff))
- fatal("Error reading partition map entry %d from %s\n", part_block,
- device);
+ printf("Making %s bootable (map entry %d)\n",
+ SPART(devs, i),
+ devs->devs[i]->part_block);
+ if (devs->devs[i]->first_bootable > 0
+ && devs->devs[i]->first_bootable < devs->devs[i]->part_block)
+ fprintf(stderr, "Warning: prior partition (entry %d) is bootable\n",
+ devs->devs[i]->first_bootable);
+ if ((fd = open(BOOTDEV(devs,i), O_RDWR)) < 0)
+ fatal("Cannot open %s for writing\n", BOOTDEV(devs,i));
+ seek_offset = (off_t)devs->devs[i]->part_block * devs->devs[i]->secsize;
+ lseek(fd, seek_offset, 0);
+ if (read(fd, buff, sizeof(buff)) != sizeof(buff)) {
+ close(fd);
+ fatal("Error reading partition map entry %d from %s\n",
+ devs->devs[i]->part_block,
+ BOOTDEV(devs,i));
+ }
mp = (struct mac_partition *) buff;
mp->status |= STATUS_BOOTABLE;
mp->boot_start = 0;
@@ -193,31 +213,41 @@
mp->boot_entry = FIRST_BASE;
mp->boot_entry2 = 0;
strncpy(mp->processor, "PowerPC", sizeof(mp->processor));
- if (lseek(fd, part_block * secsize, 0) < 0
- || write(fd, buff, sizeof(buff)) != sizeof(buff))
- fatal("Couldn't make %s%d bootable: write error\n", device,
- part_block);
+ if (lseek(fd, seek_offset, 0) < 0
+ || write(fd, buff, sizeof(buff)) != sizeof(buff)) {
+ close(fd);
+ fatal("Couldn't make %s%d bootable: write error\n",
+ BOOTDEV(devs,i),
+ devs->devs[i]->part_block);
+ }
+ close(fd);
+ }
}
-int get_partition_blocks(char *filename)
+int get_partition_blocks(char *filename, mdev_info_t * devs)
{
int fd;
- int block, i;
+ int block, i, j;
struct stat st;
if ((fd = open(filename, O_RDONLY)) == -1)
fatal("Cannot find %s", filename);
if (fstat(fd, &st) < 0)
fatal("Couldn't stat %s", filename);
- finfo.blocksize = bs;
- nsect = bs >> 9;
- for (i = 0;; i++) {
- block = i;
- if (i * bs >= st.st_size || ioctl(fd, FIBMAP, &block) < 0 || !block)
+ devs->nsect = devs->bs >> 9;
+ for (j=0; j<devs->ndevs; j++) {
+ if (SPART(devs,j)) {
+ devs->devs[j]->finfo.blocksize = devs->bs;
+
+ for (i = 0;; i++) {
+ block = i;
+ if (i * devs->bs >= st.st_size || ioctl(fd, FIBMAP, &block) < 0 ||
!block)
break;
- finfo.blknos[i] = block * nsect + doff;
+ devs->devs[j]->finfo.blknos[i] = block * devs->nsect +
devs->devs[j]->doff;
+ }
+ devs->devs[j]->finfo.nblocks = i;
+ }
}
- finfo.nblocks = i;
close(fd);
return 0;
}
@@ -238,22 +268,36 @@
return strdup(path);
}
-void write_block_table(char *device, char *config_file, int partno)
+void write_block_table(mdev_info_t *devs, char *config_file)
{
- int fd;
+ int fd, i;
+ struct first_info * finfo_p = NULL;
- if (verbose)
- printf("Writing block table to boot block on %s\n", device);
- strncpy(finfo.quik_vers, "QUIK" VERSION, sizeof(finfo.quik_vers));
- finfo.second_base = SECOND_BASE;
- finfo.conf_part = partno;
- strncpy(finfo.conf_file, config_file, sizeof(finfo.conf_file));
- if ((fd = open(device, O_RDWR)) == -1)
- fatal("Cannot open %s", device);
+ for (i=0; i<devs->ndevs; i++) {
+ if (SPART(devs,i)) {
+ if (verbose)
+ printf("Writing block table to boot block on %s\n", SPART(devs,i));
+ strncpy(devs->devs[i]->finfo.quik_vers,
+ "QUIK" VERSION,
+ sizeof(devs->devs[i]->finfo.quik_vers));
+ devs->devs[i]->finfo.second_base = SECOND_BASE;
+ devs->devs[i]->finfo.conf_part = devs->devs[i]->cpart;
+ strncpy(devs->devs[i]->finfo.conf_file,
+ config_file,
+ sizeof(devs->devs[i]->finfo.conf_file));
+ finfo_p = &(devs->devs[i]->finfo); /* All should be equal */
+ }
+ }
+ /* Seems we have to have all our bootable md devices on
+ * the SAME partitions , e.g. /dev/hda2 & /dev/hdc2.
+ * seems difficult to circumvent as we write the block table to /dev/md?
+ */
+ if ((fd = open(devs->fs_dev, O_RDWR)) == -1)
+ fatal("Cannot open %s", devs->fs_dev);
if (lseek(fd, FIRST_INFO_OFF, SEEK_SET) != FIRST_INFO_OFF)
- fatal("Seek error on %s", device);
- if (write(fd, &finfo, sizeof(finfo)) != sizeof(finfo))
- fatal("Couldn't update boot block on %s", device);
+ fatal("Seek error on %s", devs->fs_dev);
+ if (write(fd, finfo_p, sizeof(struct first_info)) != sizeof(struct
first_info))
+ fatal("Couldn't update boot block on %s", devs->fs_dev);
close(fd);
}
@@ -337,8 +381,8 @@
fatal("Couldn't seek on %s", device);
if (write(fd, buff, rc) != rc)
fatal("Couldn't write quik bootblock to %s", device);
- close(fd);
fclose(fp);
+ close(fd);
}
char *find_dev(int number)
@@ -421,23 +465,58 @@
}
}
+mdev_info_t * get_dev_info (const char * basedev, int is_md, int is_raid, int
inc_name, const struct stat st)
+{
+ mdev_info_t * out;
+ char buffer[DEV_BUFSZ];
+ /* No partitions on md devices,
+ but this macro gets the correct md minor */
+ int part = PART(st.st_dev);
+
+ if (is_md) {
+ /* We need to have the device before we can get any info */
+ strcpy(buffer, basedev);
+ if (part >= 0) { sprintf(buffer+strlen(buffer), "%d", part); }
+
+ out = md_get_info(buffer);
+ out->fs_dev = out->metadev;
+ } else {
+ out = new_mdev_info(1);
+
+ strncpy(buffer, basedev, DEV_BUFSZ);
+ if (inc_name) { buffer[7] += UNIT(st.st_dev); }
+ out->devs[0]->bootdev = (char *)malloc(strlen(buffer)+1);
+ strcpy(out->devs[0]->bootdev, buffer);
+
+ if (is_raid) { strcat(buffer, "p"); }
+ if (part != 0) {
+ sprintf(buffer+strlen(buffer), "%d", (is_raid) ? part & 7 : part);
+ }
+ out->devs[0]->spart = (char *)malloc(strlen(buffer)+1);
+ strcpy(out->devs[0]->spart, buffer);
+ out->fs_dev = out->devs[0]->spart;
+ }
+
+ return out;
+}
+
int main(int argc,char **argv)
{
char *name = NULL, *config_file, *install = NULL, *secondary, *backup;
- int c;
+ int c; int i;
int version = 0;
struct stat st1, st2;
int force_backup = 0;
int config_file_partno = 1;
char *p, *basedev=NULL;
- char bootdev[1024];
- char spart[1024];
char buffer[1024];
int force = 0;
- int inc_name, raid_dev;
+ int inc_name, raid_dev, md_dev;
extern int optind;
extern char *optarg;
+ /* md */
+ mdev_info_t * devs = NULL;
/*
* Test if we're being run on a chrp machine. We don't
@@ -524,7 +603,8 @@
unit_shift = 6;
part_mask = 0x3f;
inc_name = 1;
- raid_dev = 0;
+ raid_dev = 0;
+ md_dev = 0;
switch (MAJOR(st1.st_dev)) {
case SD_MAJOR:
unit_shift = 4;
@@ -557,6 +637,11 @@
fatal("We only support the 2 first system
drives for now");
}
break;
+ case MD_MAJOR:
+ basedev = "/dev/md";
+ inc_name = 0;
+ md_dev = 1;
+ break;
default:
p = find_dev(st1.st_dev);
if (p == NULL)
@@ -566,24 +651,15 @@
part_mask = 0;
inc_name = 0;
}
- strcpy(bootdev, basedev);
- if (inc_name)
- bootdev[7] += UNIT(st1.st_dev);
- strcpy(spart, bootdev);
- if (raid_dev)
- strcat(spart,"p");
- if (PART(st1.st_dev) != 0) {
- if (raid_dev)
- sprintf(spart+strlen(spart), "%d", PART(st1.st_dev) & 7);
- else
- sprintf(spart+strlen(spart), "%d", PART(st1.st_dev));
- }
- if (verbose)
- printf("Second-stage loader is on %s\n", spart);
+ devs = get_dev_info(basedev, md_dev, raid_dev, inc_name, st1);
- backup = chrootcpy (backup);
+ if (devs->metadev && devs->rlevel != 1)
+ fatal("RAID level other than 1 (mirror) are not supported");
+ if (verbose)
+ printf("Second-stage loader is on %s\n", devs->fs_dev);
+
if (config_file == NULL) {
config_file = chrootcpy(DFL_CONFIG);
if (stat(config_file, &st2) < 0) {
@@ -594,44 +670,74 @@
config_file = p;
}
}
- } else
+ } else {
config_file = chrootcpy (config_file);
+ }
+
+ if (verbose)
+ printf("Conffile is %s\n", config_file);
if (stat(config_file, &st2) >= 0) {
- if (MAJOR(st2.st_dev) != MAJOR(st1.st_dev)
- || UNIT(st2.st_dev) != UNIT(st1.st_dev)
- || PART(st2.st_dev) != PART(st1.st_dev))
- fatal("Config file %s has to be on the %s device (any partition)",
- config_file, bootdev);
- strcpy(buffer, config_file);
- config_file = resolve_to_dev(buffer, st2.st_dev);
+ /* If we have a metadevice, the following test
+ * prevents having a separate /boot device, which should be
+ * possible in theory. But checking for PART() seems to make this
+ * impossible even for non-md devices -- OK for now.
+ */
+ if (MAJOR(st2.st_dev) != MAJOR(st1.st_dev)
+ || UNIT(st2.st_dev) != UNIT(st1.st_dev)
+ || PART(st2.st_dev) != PART(st1.st_dev))
+ fatal("Config file %s has to be on the %s device (any partition)",
+ config_file, BOOTDEV(devs, 0));
+ strcpy(buffer, config_file);
+ buffer[strlen(config_file)] = 0x00;
+
+ config_file = resolve_to_dev(buffer, st2.st_dev);
+ if (devs->metadev) {
+ /* We are positive that conffile and second.b are
+ * on the same md device. Just get the part # from spart
+ */
+ for (i=0; i<devs->ndevs; i++) {
+ if (SPART(devs,i)) {
+ devs->devs[i]->cpart = part_from_dev(SPART(devs,i));
+ if (devs->devs[i]->cpart == 0)
+ fatal("Can't determine partition number for %s\n", SPART(devs,i));
+ }
+ }
+ } else {
if (inc_name)
- if(raid_dev)
- config_file_partno = PART(st2.st_dev) & 7;
- else
- config_file_partno = PART(st2.st_dev);
+ if(raid_dev)
+ config_file_partno = PART(st2.st_dev) & 7;
+ else
+ config_file_partno = PART(st2.st_dev);
else
- config_file_partno = 1;
+ config_file_partno = 1;
if (verbose)
- printf("Config file is on partition %d\n", config_file_partno);
+ printf("Config file is on partition %d\n", config_file_partno);
+ }
}
+
+ backup = chrootcpy (backup);
+
if (backup && !force_backup) {
if (stat(backup, &st2) < 0)
force_backup = 1;
}
- read_sb(spart, bootdev);
- if (!examine_bootblock(spart, backup, force_backup)
+ read_sb(devs);
+
+ if (!examine_bootblock(devs->fs_dev, backup, force_backup)
|| install || force) {
- if (!install)
- install = chrootcpy(DFL_PRIMARY);
- else if (*install == '/')
- install = chrootcpy(install);
- install_first_stage(spart, install);
- make_bootable(bootdev, spart);
+ if (!install)
+ install = chrootcpy(DFL_PRIMARY);
+ else if (*install == '/')
+ install = chrootcpy(install);
+ install_first_stage(devs->fs_dev, install);
+ make_bootable(devs);
}
- get_partition_blocks(secondary);
- write_block_table(spart, config_file, config_file_partno);
+ get_partition_blocks(secondary, devs);
+ write_block_table(devs, config_file);
+
+ free_mdev_info(devs);
sync();
exit(0);
}
diff -Naur quik.orig/quik/quik_md.c quik/quik/quik_md.c
--- quik.orig/quik/quik_md.c 1970-01-01 01:00:00.000000000 +0100
+++ quik/quik/quik_md.c 2005-03-08 20:23:03.994345000 +0100
@@ -0,0 +1,313 @@
+/*
+ * quik_md.c -- This file implements /dev/md device handling for quik.
+ *
+ * Copyright (C) 2005 Simon Vallet <[EMAIL PROTECTED]>
+ *
+ * Information retrieval code for md devices is derived from
+ * Detail.c in mdadm version 1.9.0, and therefore:
+ *
+ * Copyright (C) 2001-2002 Neil Brown <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <layout.h>
+#include <quik_md.h>
+
+mapping_t pers[] = {
+ { "linear", -1},
+ { "raid0", 0},
+ { "0", 0},
+ { "stripe", 0},
+ { "raid1", 1},
+ { "1", 1},
+ { "mirror", 1},
+ { "raid4", 4},
+ { "4", 4},
+ { "raid5", 5},
+ { "5", 5},
+ { "multipath", -4},
+ { "mp", -4},
+ { "raid6", 6},
+ { "6", 6},
+ { "raid10", 10},
+ { "10", 10},
+ { NULL, 0}
+};
+
+struct devmap * devlist = NULL;
+int devlist_ready = 0;
+
+/* From quik.c */
+void fatal(char *fmt,...) __attribute__ ((noreturn));
+
+mdev_info_t * md_get_info (const char * device)
+{
+
+ int d; int i=0; char * c;
+ int vers; int mdev_fd;
+ mdu_array_info_t array;
+ mdev_info_t * out = NULL;
+
+ if ((mdev_fd = open(device, O_RDONLY)) > 0) {
+ vers = md_get_version(mdev_fd);
+ if (vers > 0) {
+ if (ioctl(mdev_fd, GET_ARRAY_INFO, &array) < 0) {
+ close(mdev_fd);
+ fatal("Couldn't get array info for device %s\n", device);
+ }
+
+ out = new_mdev_info(array.raid_disks);
+ out->rlevel = array.level;
+
+ /* Not needed for the moment */
+ c = map_num(pers, array.level);
+
+ /* fprintf(stderr, "ARRAY %s level=%s num-devices=%d\n",
+ md_dev, c?c:"unknown", array.raid_disks); */
+
+ /* Get devices */
+ for (d=0; d < MD_SB_DISKS; d++) {
+ mdu_disk_info_t disk;
+ char *dv;
+ int o;
+ disk.number = d;
+ if (ioctl(mdev_fd, GET_DISK_INFO, &disk) < 0) { continue; }
+ if (d > array.raid_disks &&
+ disk.major == 0 &&
+ disk.minor == 0) { continue; }
+
+ if ((dv=map_dev(disk.major, disk.minor))) {
+ out->devs[i]->spart = (char *) malloc(strlen(dv)+1);
+ strcpy(out->devs[i]->spart, dv);
+ o = digit_offset(out->devs[i]->spart);
+ out->devs[i]->bootdev = (char *) malloc(o+1);
+ strncpy(out->devs[i]->bootdev, out->devs[i]->spart, o);
+ out->devs[i]->bootdev[o+1] = 0x00;
+ i++;
+ }
+ }
+
+ out->metadev = (char *)malloc(strlen(device)+1);
+ strcpy(out->metadev, device);
+ out->metadev[strlen(device)] = 0x00;
+ } else {
+ close(mdev_fd);
+ fatal("%s does not seem to be an md device. Exiting.", device);
+ }
+ close(mdev_fd);
+ } else {
+ fatal("Could not open device %s.\n", device);
+ }
+
+ return out;
+}
+
+int md_get_version (int fd)
+{
+ mdu_version_t vers;
+ struct stat stb;
+
+ if (fstat(fd, &stb)<0) {
+ return -1;
+ }
+ if ((S_IFMT&stb.st_mode) != S_IFBLK) {
+ fprintf(stderr, "This is not a block device.\n");
+ return -1;
+ }
+
+ if (ioctl(fd, RAID_VERSION, &vers) == 0) {
+ return (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
+ }
+
+ if (errno == EACCES) {
+ perror("Could not access the given device");
+ return -1;
+ } else {
+ perror("get_version");
+ }
+
+ if (major(stb.st_rdev) == MD_MAJOR)
+ return (3600);
+
+ return -1;
+}
+
+/*
+ * Returns the offset of the first digit
+ */
+int digit_offset (const char * str)
+{
+ int l; int o = -1;
+
+ if (str) {
+ l = strlen(str);
+ while (++o<l && !isdigit(str[o]));
+ }
+ return o;
+}
+
+
+char * map_num(mapping_t *map, int num)
+{
+ while (map->name) {
+ if (map->num == num)
+ return map->name;
+ map++;
+ }
+ return NULL;
+}
+
+/*
+ * Find a block device with the right major/minor number.
+ * Avoid /dev/mdNN and /dev/md/dNN if possible
+ */
+char * map_dev(int major, int minor)
+{
+ struct devmap *p;
+ char *std = NULL;
+ if (!devlist_ready) {
+ nftw("/dev", add_dev, 10, FTW_PHYS);
+ devlist_ready=1;
+ }
+
+ for (p=devlist; p; p=p->next)
+ if (p->major == major &&
+ p->minor == minor) {
+ if (is_standard(p->name, NULL))
+ std = p->name;
+ else
+ return p->name;
+ }
+ return std;
+}
+
+
+int is_standard(char *dev, int *nump)
+{
+ /* tests if dev is a "standard" md dev name.
+ * i.e if the last component is "/dNN" or "/mdNN",
+ * where NN is a string of digits
+ */
+ char *d = strrchr(dev, '/');
+ int type=0;
+ int num;
+ if (!d)
+ return 0;
+ if (strncmp(d, "/d",2)==0)
+ d += 2, type=1; /* /dev/md/dN{pM} */
+ else if (strncmp(d, "/md_d", 5)==0)
+ d += 5, type=1; /* /dev/md_dNpM */
+ else if (strncmp(d, "/md", 3)==0)
+ d += 3, type=-1; /* /dev/mdN */
+ else if (d-dev > 3 && strncmp(d-2, "md/", 3)==0)
+ type = -1; /* /dev/md/N */
+ else
+ return 0;
+ if (!*d)
+ return 0;
+ num = atoi(d);
+ while (isdigit(*d))
+ d++;
+ if (*d)
+ return 0;
+ if (nump) *nump = num;
+
+ return type;
+}
+
+int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)
+{
+ if ((stb->st_mode&S_IFMT)== S_IFBLK) {
+ char *n = strdup(name);
+ struct devmap *dm = malloc(sizeof(*dm));
+ if (dm) {
+ dm->major = major(stb->st_rdev);
+ dm->minor = minor(stb->st_rdev);
+ dm->name = n;
+ dm->next = devlist;
+ devlist = dm;
+ }
+ }
+ return 0;
+}
+
+/* Does NOT allocate space for individual strings,
+ * i.e. bootdevs[i] or metadev
+ */
+mdev_info_t * new_mdev_info (unsigned char ndevs)
+{
+ int i;
+ mdev_info_t * out = (mdev_info_t *)malloc(sizeof(mdev_info_t));
+
+ out->ndevs = ndevs;
+ out->bs = out->nsect = 0;
+ out->devs = (dev_info_t **)malloc(ndevs*sizeof(dev_info_t *));
+ for (i=0; i<ndevs; i++) {
+ out->devs[i] = new_dev_info();
+ }
+ out->metadev = out->fs_dev = NULL;
+ out->rlevel = INT_MAX;
+
+ return out;
+}
+
+dev_info_t * new_dev_info ()
+{
+ dev_info_t * out = (dev_info_t *)malloc(sizeof(dev_info_t));
+
+ out->spart = out->bootdev = NULL;
+ out->part_block = out->secsize = 0;
+ out->first_bootable = 0;
+ out->doff = 0;
+ out->cpart = 0;
+
+ return out;
+}
+
+void free_mdev_info(mdev_info_t * obs)
+{
+ int i;
+
+ if (obs) {
+ /* fs_dev is a convenience pointer, not free()ed */
+ if (obs->metadev) free(obs->metadev);
+ if (obs->devs) {
+ for (i=0; i<obs->ndevs; i++) {
+ free_dev_info(obs->devs[i]);
+ }
+ free(obs->devs);
+ }
+ free(obs);
+ }
+}
+
+void free_dev_info (dev_info_t * obs)
+{
+ if (obs) {
+ if (obs->bootdev) free(obs->bootdev);
+ if (obs->spart) free(obs->spart);
+ free(obs);
+ }
+}
diff -Naur quik.orig/README.md quik/README.md
--- quik.orig/README.md 1970-01-01 01:00:00.000000000 +0100
+++ quik/README.md 2005-03-08 20:29:49.317726680 +0100
@@ -0,0 +1,33 @@
+
+-----------------------------
+README -- MD support for quik
+-----------------------------
+
+This version of quik includes linux-style /dev/md support, with the
+following limitations :
+
+* It supports n-way mirrors (RAID1 arrays) only, and it is unlikely
+that support for other RAID levels will be added, unless we can
+find a reliable way to get the conffile partition number on
+a striped filesystem.
+
+* Further, the bootable metadevice (typically /) *must* be assembled
+from partitions having the same partition number (e.g. /dev/hda2 and
+/dev/hdc2, *not* /dev/hda2 and /dev/hdc3). This is necessary because
+we write the bootblock to the metadevice, not the underlying
+partitions. Again, it is unlikely that this will change.
+
+* The conffile *must* reside on the bootable partition/metadevice.
+This means that a separate /boot partition will *not* work, unless
+the configuration file is in /boot.
+
+* This version does not recognize spare devices, and will try
+to write a boot block on them -- if you have any spare drives in
+your array, remove them before running quik. You can always re-add
+them later
+This will be fixed in a future version.
+
+* LVM volumes are not supported, but will be if at all possible.
+
+
+Simon Vallet -- 2005/03
---------------------------------------
Received: (at 298606-close) by bugs.debian.org; 25 Mar 2005 16:23:05 +0000
>From [EMAIL PROTECTED] Fri Mar 25 08:23:05 2005
Return-path: <[EMAIL PROTECTED]>
Received: from newraff.debian.org [208.185.25.31] (mail)
by spohr.debian.org with esmtp (Exim 3.35 1 (Debian))
id 1DEraS-0008P3-00; Fri, 25 Mar 2005 08:23:04 -0800
Received: from katie by newraff.debian.org with local (Exim 3.35 1 (Debian))
id 1DErIC-000448-00; Fri, 25 Mar 2005 11:04:12 -0500
From: Peter De Schrijver (p2) <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
X-Katie: $Revision: 1.55 $
Subject: Bug#298606: fixed in quik 2.1-5
Message-Id: <[EMAIL PROTECTED]>
Sender: Archive Administrator <[EMAIL PROTECTED]>
Date: Fri, 25 Mar 2005 11:04:12 -0500
Delivered-To: [EMAIL PROTECTED]
X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2005_01_02
(1.212-2003-09-23-exp) on spohr.debian.org
X-Spam-Status: No, hits=-6.0 required=4.0 tests=BAYES_00,HAS_BUG_NUMBER
autolearn=no version=2.60-bugs.debian.org_2005_01_02
X-Spam-Level:
Source: quik
Source-Version: 2.1-5
We believe that the bug you reported is fixed in the latest version of
quik, which is due to be installed in the Debian FTP archive:
quik_2.1-5.diff.gz
to pool/main/q/quik/quik_2.1-5.diff.gz
quik_2.1-5.dsc
to pool/main/q/quik/quik_2.1-5.dsc
quik_2.1-5_powerpc.deb
to pool/main/q/quik/quik_2.1-5_powerpc.deb
A summary of the changes between this version and the previous one is
attached.
Thank you for reporting the bug, which will now be closed. If you
have further comments please address them to [EMAIL PROTECTED],
and the maintainer will reopen the bug report if appropriate.
Debian distribution maintenance software
pp.
Peter De Schrijver (p2) <[EMAIL PROTECTED]> (supplier of updated quik package)
(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [EMAIL PROTECTED])
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Format: 1.7
Date: Sun, 20 Mar 2005 22:58:46 -0600
Source: quik
Binary: quik
Architecture: source powerpc
Version: 2.1-5
Distribution: unstable
Urgency: low
Maintainer: Peter De Schrijver (p2) <[EMAIL PROTECTED]>
Changed-By: Peter De Schrijver (p2) <[EMAIL PROTECTED]>
Description:
quik - Bootloader for PowerMac or CHRP systems
Closes: 298606
Changes:
quik (2.1-5) unstable; urgency=low
.
* Added support for md devices. Thanks to Simon Vallet. (Closes: #298606)
Files:
efd22a7a7d6ffeb9ad4a7367512b4fc1 660 base important quik_2.1-5.dsc
4d55ed69e5307a1c59a91327eaff55ac 35901 base important quik_2.1-5.diff.gz
e24e717e2d952c90754d15469770de26 46492 base important quik_2.1-5_powerpc.deb
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
iD8DBQFCPlW7KLKVw/RurbsRAgxFAJ4qoRgFCMYRlS9krG2CuXFjRA9vbQCfQOkF
mzVE7Q6Wu7cWW2XGdimigF8=
=wq0A
-----END PGP SIGNATURE-----
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]