chiark / gitweb /
[PATCH] This fixes a silly mistake in how udevinfo prints the major and minor
[elogind.git] / extras / volume_id / volume_id.c
index 99aed6c96b608ba97192f2b10f346380d02bb0d8..42d658895f11ffe8f68d37eb170ee85c78527fbf 100644 (file)
@@ -263,6 +263,36 @@ static void free_buffer(struct volume_id *id)
        }
 }
 
+#define HPT37X_CONFIG_OFF              0x1200
+#define HPT37X_MAGIC_OK                        0x5a7816f0
+#define HPT37X_MAGIC_BAD               0x5a7816fd
+static int probe_highpoint_ataraid(struct volume_id *id, __u64 off)
+{
+       struct hpt37x {
+               __u8    filler1[32];
+               __u32   magic;
+               __u32   magic_0;
+               __u32   magic_1;
+       } __attribute__((packed)) *hpt;
+
+       const __u8 *buf;
+
+       buf = get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200);
+       if (buf == NULL)
+               return -1;
+
+       hpt = (struct hpt37x *) buf;
+
+       if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD)
+               return -1;
+
+       id->usage_id = VOLUME_ID_RAID;
+       id->type_id = VOLUME_ID_HPTRAID;
+       id->type = "hpt_ataraid_member";
+
+       return 0;
+}
+
 #define LVM1_SB_OFF                    0x400
 #define LVM1_MAGIC                     "HM"
 static int probe_lvm1(struct volume_id *id, __u64 off)
@@ -321,7 +351,7 @@ static int probe_lvm2(struct volume_id *id, __u64 off)
 found:
        strncpy(id->type_version, lvm->type, 8);
        id->usage_id = VOLUME_ID_RAID;
-       id->type_id = VOLUME_ID_LVM1;
+       id->type_id = VOLUME_ID_LVM2;
        id->type = "LVM2_member";
 
        return 0;
@@ -461,6 +491,8 @@ static int probe_msdos_part_table(struct volume_id *id, __u64 off)
 
                p = &id->partitions[i];
 
+               p->partition_type_raw = part[i].sys_ind;
+
                if (is_extended(part[i].sys_ind)) {
                        dbg("found extended partition at 0x%llx", poff);
                        p->usage_id = VOLUME_ID_PARTITIONTABLE;
@@ -535,6 +567,9 @@ static int probe_msdos_part_table(struct volume_id *id, __u64 off)
                                p->off = current + poff;
                                p->len = plen;
                                id->partition_count++;
+
+                               p->partition_type_raw = part[i].sys_ind;
+
                                if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) {
                                        dbg("to many partitions");
                                        next = 0;
@@ -918,13 +953,13 @@ valid:
 
        for (i = 0; i <= root_dir_entries; i++) {
                /* end marker */
-               if (dir[i].attr == 0x00) {
+               if (dir[i].name[0] == 0x00) {
                        dbg("end of dir");
                        break;
                }
 
                /* empty entry */
-               if (dir[i].attr == 0xe5)
+               if (dir[i].name[0] == 0xe5)
                        continue;
 
                if (dir[i].attr == FAT_ATTR_VOLUME) {
@@ -976,13 +1011,13 @@ fat32:
 
                for (i = 0; i <= count; i++) {
                        /* end marker */
-                       if (dir[i].attr == 0x00) {
+                       if (dir[i].name[0] == 0x00) {
                                dbg("end of dir");
                                goto fat32_label;
                        }
 
                        /* empty entry */
-                       if (dir[i].attr == 0xe5)
+                       if (dir[i].name[0] == 0xe5)
                                continue;
 
                        if (dir[i].attr == FAT_ATTR_VOLUME) {
@@ -1016,7 +1051,7 @@ fat32_label:
                set_label_raw(id, vs->type.fat32.label, 11);
                set_label_string(id, vs->type.fat32.label, 11);
        }
-       set_uuid(id, vs->type.fat32.serno, UUID_DCE);
+       set_uuid(id, vs->type.fat32.serno, UUID_DOS);
 
 found:
        id->usage_id = VOLUME_ID_FILESYSTEM;
@@ -2033,20 +2068,30 @@ int volume_id_probe(struct volume_id *id,
        case VOLUME_ID_LVM2:
                rc = probe_lvm2(id, off);
                break;
+       case VOLUME_ID_HPTRAID:
+               rc = probe_highpoint_ataraid(id, off);
+               break;
        case VOLUME_ID_ALL:
        default:
+               /* probe for raid first, cause fs probes may be successful on raid members */
                rc = probe_linux_raid(id, off, size);
                if (rc == 0)
                        break;
-
-               /* signature in the first block */
-               rc = probe_ntfs(id, off);
+               rc = probe_lvm1(id, off);
                if (rc == 0)
                        break;
-               rc = probe_vfat(id, off);
+               rc = probe_lvm2(id, off);
+               if (rc == 0)
+                       break;
+               rc = probe_highpoint_ataraid(id, off);
                if (rc == 0)
                        break;
+
+               /* signature in the first block, only small buffer needed */
                rc = probe_msdos_part_table(id, off);
+               if (rc == 0)
+                       break;
+               rc = probe_vfat(id, off);
                if (rc == 0)
                        break;
                rc = probe_mac_partition_map(id, off);
@@ -2083,10 +2128,7 @@ int volume_id_probe(struct volume_id *id,
                rc = probe_ufs(id, off);
                if (rc == 0)
                        break;
-               rc = probe_lvm1(id, off);
-               if (rc == 0)
-                       break;
-               rc = probe_lvm2(id, off);
+               rc = probe_ntfs(id, off);
                if (rc == 0)
                        break;
 
@@ -2122,7 +2164,7 @@ struct volume_id *volume_id_open_node(const char *path)
        struct volume_id *id;
        int fd;
 
-       fd = open(path, O_RDONLY | O_NONBLOCK);
+       fd = open(path, O_RDONLY);
        if (fd < 0) {
                dbg("unable to open '%s'", path);
                return NULL;