From: kay.sievers@vrfy.org Date: Fri, 11 Mar 2005 23:14:38 +0000 (+0100) Subject: [PATCH] volume_id: version 42 X-Git-Tag: 055~19 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=afa3c553b1ff0ceb3e038cdf86d9261a8b8aa5d6 [PATCH] volume_id: version 42 --- diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 68d80d689..acd26ff10 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -3,6 +3,12 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/fat.o \ $(VOLUME_ID_BASE)/hfs.o \ $(VOLUME_ID_BASE)/highpoint.o \ + $(VOLUME_ID_BASE)/isw_raid.o \ + $(VOLUME_ID_BASE)/lsi_raid.o \ + $(VOLUME_ID_BASE)/via_raid.o \ + $(VOLUME_ID_BASE)/silicon_raid.o \ + $(VOLUME_ID_BASE)/nvidia_raid.o \ + $(VOLUME_ID_BASE)/promise_raid.o \ $(VOLUME_ID_BASE)/iso9660.o \ $(VOLUME_ID_BASE)/jfs.o \ $(VOLUME_ID_BASE)/linux_raid.o \ @@ -30,6 +36,12 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/fat.h \ $(VOLUME_ID_BASE)/hfs.h \ $(VOLUME_ID_BASE)/highpoint.h \ + $(VOLUME_ID_BASE)/isw_raid.h \ + $(VOLUME_ID_BASE)/lsi_raid.h \ + $(VOLUME_ID_BASE)/via_raid.h \ + $(VOLUME_ID_BASE)/silicon_raid.h \ + $(VOLUME_ID_BASE)/nvidia_raid.h \ + $(VOLUME_ID_BASE)/promise_raid.h \ $(VOLUME_ID_BASE)/iso9660.h \ $(VOLUME_ID_BASE)/jfs.h \ $(VOLUME_ID_BASE)/linux_raid.h \ diff --git a/extras/volume_id/volume_id/highpoint.c b/extras/volume_id/volume_id/highpoint.c index 72f7d2842..938a8934e 100644 --- a/extras/volume_id/volume_id/highpoint.c +++ b/extras/volume_id/volume_id/highpoint.c @@ -39,20 +39,28 @@ #include "util.h" #include "highpoint.h" -struct hpt37x { +struct hpt37x_meta { __u8 filler1[32]; __u32 magic; - __u32 magic_0; - __u32 magic_1; -} __attribute__((packed)) *hpt; +} __attribute__((packed)); + +struct hpt45x_meta { + __u32 magic; +} __attribute__((packed)); #define HPT37X_CONFIG_OFF 0x1200 #define HPT37X_MAGIC_OK 0x5a7816f0 #define HPT37X_MAGIC_BAD 0x5a7816fd -int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) +#define HPT45X_MAGIC_OK 0x5a7816f3 +#define HPT45X_MAGIC_BAD 0x5a7816fd + + +int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off) { const __u8 *buf; + struct hpt37x_meta *hpt; + __u32 magic; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -60,13 +68,42 @@ int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) if (buf == NULL) return -1; - hpt = (struct hpt37x *) buf; + hpt = (struct hpt37x_meta *) buf; + magic = le32_to_cpu(hpt->magic); + if (magic != HPT37X_MAGIC_OK && magic != HPT37X_MAGIC_BAD) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "highpoint_raid_member"; + + return 0; +} + +int volume_id_probe_highpoint_45x_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + struct hpt45x_meta *hpt; + __u64 meta_off; + __u32 magic; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-11) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; - if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD) + hpt = (struct hpt45x_meta *) buf; + magic = le32_to_cpu(hpt->magic); + if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD) return -1; volume_id_set_usage(id, VOLUME_ID_RAID); - id->type = "hpt_ataraid_member"; + id->type = "highpoint_raid_member"; return 0; } diff --git a/extras/volume_id/volume_id/highpoint.h b/extras/volume_id/volume_id/highpoint.h index 5a5614afe..7cc2ac0cb 100644 --- a/extras/volume_id/volume_id/highpoint.h +++ b/extras/volume_id/volume_id/highpoint.h @@ -21,6 +21,7 @@ #ifndef _VOLUME_ID_HIGHPOINT_ #define _VOLUME_ID_HIGHPOINT_ -extern int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off); +extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off); +extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, __u64 off, __u64 size); #endif diff --git a/extras/volume_id/volume_id/isw_raid.c b/extras/volume_id/volume_id/isw_raid.c new file mode 100644 index 000000000..c703f3fe2 --- /dev/null +++ b/extras/volume_id/volume_id/isw_raid.c @@ -0,0 +1,79 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "isw_raid.h" + +struct isw_meta { + __u8 sig[32]; + __u32 check_sum; + __u32 mpb_size; + __u32 family_num; + __u32 generation_num; +} __attribute__((packed)); + +#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " + + +int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct isw_meta *isw; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-2) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + isw = (struct isw_meta *) buf; + if (memcmp(isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + strncpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); + id->type = "isw_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/isw_raid.h b/extras/volume_id/volume_id/isw_raid.h new file mode 100644 index 000000000..4bfd3bb52 --- /dev/null +++ b/extras/volume_id/volume_id/isw_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_ISW_RAID_ +#define _VOLUME_ID_ISW_RAID_ + +extern int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/linux_raid.c b/extras/volume_id/volume_id/linux_raid.c index e7db4031d..598002ec4 100644 --- a/extras/volume_id/volume_id/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid.c @@ -67,7 +67,8 @@ int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) __u64 sboff; __u8 uuid[16]; - dbg("probing at offset 0x%llx", (unsigned long long) off); + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); if (size < 0x10000) return -1; @@ -86,7 +87,7 @@ int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) memcpy(&uuid[4], &mdp->set_uuid1, 12); volume_id_set_uuid(id, uuid, UUID_DCE); - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u", + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", le32_to_cpu(mdp->major_version), le32_to_cpu(mdp->minor_version), le32_to_cpu(mdp->patch_version)); diff --git a/extras/volume_id/volume_id/lsi_raid.c b/extras/volume_id/volume_id/lsi_raid.c new file mode 100644 index 000000000..e411fbc26 --- /dev/null +++ b/extras/volume_id/volume_id/lsi_raid.c @@ -0,0 +1,73 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "lsi_raid.h" + +struct lsi_meta { + __u8 sig[6]; +} __attribute__((packed)); + +#define LSI_SIGNATURE "$XIDE$" + +int volume_id_probe_lsi_mega_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct lsi_meta *lsi; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + lsi = (struct lsi_meta *) buf; + if (memcmp(lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "lsi_mega_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/lsi_raid.h b/extras/volume_id/volume_id/lsi_raid.h new file mode 100644 index 000000000..b3ee0bb7f --- /dev/null +++ b/extras/volume_id/volume_id/lsi_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_LSI_RAID_ +#define _VOLUME_ID_LSI_RAID_ + +extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/ntfs.c b/extras/volume_id/volume_id/ntfs.c index 8f31735a2..f9df0e9cc 100644 --- a/extras/volume_id/volume_id/ntfs.c +++ b/extras/volume_id/volume_id/ntfs.c @@ -184,7 +184,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { dbg("found info, len %i", val_len); info = (struct volume_info*) (((__u8 *) attr) + val_off); - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", info->major_ver, info->minor_ver); } diff --git a/extras/volume_id/volume_id/nvidia_raid.c b/extras/volume_id/volume_id/nvidia_raid.c new file mode 100644 index 000000000..ad7663179 --- /dev/null +++ b/extras/volume_id/volume_id/nvidia_raid.c @@ -0,0 +1,77 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "nvidia_raid.h" + +struct nvidia_meta { + __u8 vendor[8]; + __u32 size; + __u32 chksum; + __u16 version; +} __attribute__((packed)); + +#define NVIDIA_SIGNATURE "NVIDIA" + +int volume_id_probe_nvidia_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct nvidia_meta *nv; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-2) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + nv = (struct nvidia_meta *) buf; + if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", le16_to_cpu(nv->version)); + id->type = "nvidia_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/nvidia_raid.h b/extras/volume_id/volume_id/nvidia_raid.h new file mode 100644 index 000000000..f892be559 --- /dev/null +++ b/extras/volume_id/volume_id/nvidia_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_NVIDIA_RAID_ +#define _VOLUME_ID_NVIDIA_RAID_ + +extern int volume_id_probe_nvidia_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/promise_raid.c b/extras/volume_id/volume_id/promise_raid.c new file mode 100644 index 000000000..8fda14945 --- /dev/null +++ b/extras/volume_id/volume_id/promise_raid.c @@ -0,0 +1,83 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "promise_raid.h" + +struct promise_meta { + __u8 sig[24]; +} __attribute__((packed)); + +#define PDC_CONFIG_OFF 0x1200 +#define PDC_SIGNATURE "Promise Technology, Inc." + +int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + struct promise_meta *pdc; + unsigned int i; + static unsigned int sectors[] = { + 63, 255, 256, 16, 399, 0 + }; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x40000) + return -1; + + for (i = 0; sectors[i] != 0; i++) { + __u64 meta_off; + + meta_off = ((size / 0x200) - sectors[i]) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + pdc = (struct promise_meta *) buf; + if (memcmp(pdc->sig, PDC_SIGNATURE, sizeof(PDC_SIGNATURE)-1) == 0) + goto found; + } + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "promise_fasttrack_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/promise_raid.h b/extras/volume_id/volume_id/promise_raid.h new file mode 100644 index 000000000..554bcb97d --- /dev/null +++ b/extras/volume_id/volume_id/promise_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_PROMISE_RAID_ +#define _VOLUME_ID_PROMISE_RAID_ + +extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/silicon_raid.c b/extras/volume_id/volume_id/silicon_raid.c new file mode 100644 index 000000000..e528a34ce --- /dev/null +++ b/extras/volume_id/volume_id/silicon_raid.c @@ -0,0 +1,90 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "silicon_raid.h" + +struct silicon_meta { + __u8 unknown0[0x2E]; + __u8 ascii_version[0x36 - 0x2E]; + __u8 diskname[0x56 - 0x36]; + __u8 unknown1[0x60 - 0x56]; + __u32 magic; + __u32 unknown1a[0x6C - 0x64]; + __u32 array_sectors_low; + __u32 array_sectors_high; + __u8 unknown2[0x78 - 0x74]; + __u32 thisdisk_sectors; + __u8 unknown3[0x100 - 0x7C]; + __u8 unknown4[0x104 - 0x100]; + __u16 product_id; + __u16 vendor_id; + __u16 minor_ver; + __u16 major_ver; +} __attribute__((packed)); + +#define SILICON_MAGIC 0x2F000000 + +int volume_id_probe_silicon_medley_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct silicon_meta *sil; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + sil = (struct silicon_meta *) buf; + if (le32_to_cpu(sil->magic) != SILICON_MAGIC) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", + le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); + id->type = "silicon_medley_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/silicon_raid.h b/extras/volume_id/volume_id/silicon_raid.h new file mode 100644 index 000000000..b88e80bb1 --- /dev/null +++ b/extras/volume_id/volume_id/silicon_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_SILICON_RAID_ +#define _VOLUME_ID_SILICON_RAID_ + +extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/via_raid.c b/extras/volume_id/volume_id/via_raid.c new file mode 100644 index 000000000..393890eb2 --- /dev/null +++ b/extras/volume_id/volume_id/via_raid.c @@ -0,0 +1,88 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "via_raid.h" + +struct via_meta { + __u16 signature; + __u8 version_number; + struct via_array { + __u16 disk_bits; + __u8 disk_array_ex; + __u32 capacity_low; + __u32 capacity_high; + __u32 serial_checksum; + } __attribute((packed)) array; + __u32 serial_checksum[8]; + __u8 checksum; +} __attribute__((packed)); + +#define VIA_SIGNATURE 0xAA55 + +int volume_id_probe_via_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct via_meta *via; + + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); + + if (size < 0x10000) + return -1; + + meta_off = ((size / 0x200)-1) * 0x200; + + buf = volume_id_get_buffer(id, off + meta_off, 0x200); + if (buf == NULL) + return -1; + + via = (struct via_meta *) buf; + if (le16_to_cpu(via->signature) != VIA_SIGNATURE) + return -1; + + if (via->version_number > 1) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + snprintf(id->type_version, sizeof(id->type_version)-1, "%u", via->version_number); + id->type = "via_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/via_raid.h b/extras/volume_id/volume_id/via_raid.h new file mode 100644 index 000000000..2d0651c41 --- /dev/null +++ b/extras/volume_id/volume_id/via_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_VIA_RAID_ +#define _VOLUME_ID_VIA_RAID_ + +extern int volume_id_probe_via_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 22d30ee74..3fe8562e3 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -52,6 +52,12 @@ #include "iso9660.h" #include "udf.h" #include "highpoint.h" +#include "isw_raid.h" +#include "lsi_raid.h" +#include "via_raid.h" +#include "silicon_raid.h" +#include "nvidia_raid.h" +#include "promise_raid.h" #include "luks.h" #include "linux_swap.h" #include "linux_raid.h" @@ -70,8 +76,31 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l return -EINVAL; /* probe for raid first, cause fs probes may be successful on raid members */ - if (volume_id_probe_linux_raid(id, off, size) == 0) - goto exit; + if (size) { + if (volume_id_probe_linux_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_intel_software_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_lsi_mega_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_via_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_silicon_medley_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_nvidia_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_promise_fasttrack_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_highpoint_45x_raid(id, off, size) == 0) + goto exit; + } if (volume_id_probe_lvm1(id, off) == 0) goto exit; @@ -79,7 +108,7 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_lvm2(id, off) == 0) goto exit; - if (volume_id_probe_highpoint_ataraid(id, off) == 0) + if (volume_id_probe_highpoint_37x_raid(id, off) == 0) goto exit; if (volume_id_probe_luks(id, off) == 0) diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 0a273fba5..63f95132d 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 41 +#define VOLUME_ID_VERSION 42 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36