~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to shlibs/blkid/src/topology/md.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Linux Software RAID (md) topology
3
 
 * -- this is fallback for old systems where the topology information is not
4
 
 *    exported by sysfs
5
 
 *
6
 
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
7
 
 *
8
 
 * This file may be redistributed under the terms of the
9
 
 * GNU Lesser General Public License.
10
 
 *
11
 
 */
12
 
#include <errno.h>
13
 
#include <fcntl.h>
14
 
#include <stdint.h>
15
 
#include <stdio.h>
16
 
#include <stdlib.h>
17
 
#include <string.h>
18
 
#include <sys/ioctl.h>
19
 
#include <sys/stat.h>
20
 
#include <sys/types.h>
21
 
#include <unistd.h>
22
 
 
23
 
#include "topology.h"
24
 
 
25
 
#ifndef MD_MAJOR
26
 
#define MD_MAJOR        9
27
 
#endif
28
 
 
29
 
#ifndef _IOT__IOTBASE_uint32_t
30
 
#define _IOT__IOTBASE_uint32_t IOT_SIMPLE(uint32_t)
31
 
#endif
32
 
#define _IOT_md_array_info _IOT (_IOTS(uint32_t), 18, 0, 0, 0, 0)
33
 
#define GET_ARRAY_INFO          _IOR (MD_MAJOR, 0x11, struct md_array_info)
34
 
 
35
 
struct md_array_info {
36
 
        /*
37
 
         * Generic constant information
38
 
         */
39
 
        uint32_t major_version;
40
 
        uint32_t minor_version;
41
 
        uint32_t patch_version;
42
 
        uint32_t ctime;
43
 
        uint32_t level;
44
 
        uint32_t size;
45
 
        uint32_t nr_disks;
46
 
        uint32_t raid_disks;
47
 
        uint32_t md_minor;
48
 
        uint32_t not_persistent;
49
 
 
50
 
        /*
51
 
         * Generic state information
52
 
         */
53
 
        uint32_t utime;   /*  0 Superblock update time            */
54
 
        uint32_t state;   /*  1 State bits (clean, ...)           */
55
 
        uint32_t active_disks;  /*  2 Number of currently active disks  */
56
 
        uint32_t working_disks; /*  3 Number of working disks             */
57
 
        uint32_t failed_disks;  /*  4 Number of failed disks              */
58
 
        uint32_t spare_disks;     /*  5 Number of spare disks             */
59
 
 
60
 
        /*
61
 
         * Personality information
62
 
         */
63
 
        uint32_t layout;          /*  0 the array's physical layout       */
64
 
        uint32_t chunk_size;      /*  1 chunk size in bytes               */
65
 
 
66
 
};
67
 
 
68
 
static int is_md_device(dev_t devno)
69
 
{
70
 
        if (major(devno) == MD_MAJOR)
71
 
                return 1;
72
 
        return blkid_driver_has_major("md", major(devno));
73
 
}
74
 
 
75
 
static int probe_md_tp(blkid_probe pr, const struct blkid_idmag *mag)
76
 
{
77
 
        int fd = -1;
78
 
        dev_t disk = 0;
79
 
        dev_t devno = blkid_probe_get_devno(pr);
80
 
        struct md_array_info md;
81
 
 
82
 
        if (!devno)
83
 
                goto nothing;           /* probably not a block device */
84
 
 
85
 
        if (!is_md_device(devno))
86
 
                goto nothing;
87
 
 
88
 
        if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk))
89
 
                goto nothing;
90
 
 
91
 
        if (disk == devno)
92
 
                fd = pr->fd;
93
 
        else {
94
 
                char *diskpath = blkid_devno_to_devname(disk);
95
 
 
96
 
                if (!diskpath)
97
 
                        goto nothing;
98
 
 
99
 
                fd = open(diskpath, O_RDONLY);
100
 
                free(diskpath);
101
 
 
102
 
                if (fd == -1)
103
 
                        goto nothing;
104
 
        }
105
 
 
106
 
        memset(&md, 0, sizeof(md));
107
 
 
108
 
        if (ioctl(fd, GET_ARRAY_INFO, &md))
109
 
                goto nothing;
110
 
 
111
 
        if (fd != pr->fd)
112
 
                close(fd);
113
 
 
114
 
        /*
115
 
         * Ignore levels we don't want aligned (e.g. linear)
116
 
         * and deduct disk(s) from stripe width on RAID4/5/6
117
 
         */
118
 
        switch (md.level) {
119
 
        case 6:
120
 
                md.raid_disks--;
121
 
                /* fallthrough */
122
 
        case 5:
123
 
        case 4:
124
 
                md.raid_disks--;
125
 
                /* fallthrough */
126
 
        case 1:
127
 
        case 0:
128
 
        case 10:
129
 
                break;
130
 
        default:
131
 
                goto nothing;
132
 
        }
133
 
 
134
 
        blkid_topology_set_minimum_io_size(pr, md.chunk_size);
135
 
        blkid_topology_set_optimal_io_size(pr, md.chunk_size * md.raid_disks);
136
 
 
137
 
        return 0;
138
 
 
139
 
nothing:
140
 
        if (fd != -1 && fd != pr->fd)
141
 
                close(fd);
142
 
        return 1;
143
 
}
144
 
 
145
 
const struct blkid_idinfo md_tp_idinfo =
146
 
{
147
 
        .name           = "md",
148
 
        .probefunc      = probe_md_tp,
149
 
        .magics         = BLKID_NONE_MAGIC
150
 
};
151