summaryrefslogtreecommitdiff
blob: 8c40082ec469bdcbdc96c3b7b1eb0dfdc1977e49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>

#include "stats_linux.h"
#include "internal.h"
#include "xen/block_stats.h"
#include "testutils.h"
#include "command.h"

static void testQuietError(void *userData ATTRIBUTE_UNUSED,
                           virErrorPtr error ATTRIBUTE_UNUSED)
{
    /* nada */
}

static int testDevice(const char *path, int expect)
{
    int actual = xenLinuxDomainDeviceID(1, path);

    if (actual == expect) {
        return 0;
    } else {
        if (virTestGetDebug())
            fprintf(stderr, "Expect %-6d Actual %-6d\n", expect, actual);
        return -1;
    }
}

struct testInfo
{
    const char *dev;
    int num;
};

static int testDeviceHelper(const void *data)
{
    const struct testInfo *info = data;
    return testDevice(info->dev, info->num);
}

static int
mymain(void)
{
    int ret = 0;
    int status;
    virCommandPtr cmd;
    struct utsname ut;

    /* Skip test if xend is not running.  Calling xend on a non-xen
       kernel causes some versions of xend to issue a crash report, so
       we first probe uname results.  */
    uname(&ut);
    if (strstr(ut.release, "xen") == NULL)
        return EXIT_AM_SKIP;
    cmd = virCommandNewArgList("/usr/sbin/xend", "status", NULL);
    if (virCommandRun(cmd, &status) != 0 || status != 0) {
        virCommandFree(cmd);
        return EXIT_AM_SKIP;
    }
    virCommandFree(cmd);

    /* Some of our tests deliberately test failure cases, so
     * register a handler to stop error messages cluttering
     * up display
     */
    if (!virTestGetDebug())
        virSetErrorFunc(NULL, testQuietError);

#define DO_TEST(dev, num)                                              \
    do {                                                               \
        struct testInfo info = { dev, num };                           \
        if (virtTestRun("Device " dev " -> " # num,                    \
                        1, testDeviceHelper, &info) < 0)               \
            ret = -1;                                                  \
    } while (0)

    /********************************
     * Xen paravirt disks
     ********************************/

    DO_TEST("xvd", -1);

    /* first valid disk */
    DO_TEST("xvda", 51712);
    DO_TEST("xvda1", 51713);
    DO_TEST("xvda15", 51727);
    /* Last non-extended disk */
    DO_TEST("xvdp", 51952);
    DO_TEST("xvdp1", 51953);
    DO_TEST("xvdp15", 51967);

    /* First extended disk */
    DO_TEST("xvdq", 268439552);
    DO_TEST("xvdq1", 268439553);
    DO_TEST("xvdq15", 268439567);
    /* Last extended disk */
    DO_TEST("xvdiz", 268501760);
    DO_TEST("xvdiz1", 268501761);
    DO_TEST("xvdiz15", 268501775);

    /* Disk letter too large */
    DO_TEST("xvdja", -1);

    /* missing disk letter */
    DO_TEST("xvd1", -1);
    /* partition too large */
    DO_TEST("xvda16", -1);
    /* partition too small */
    DO_TEST("xvda0", -1);
    /* leading zeros */
    DO_TEST("xvda01", -1);
    /* leading + */
    DO_TEST("xvda+1", -1);
    /* leading - */
    DO_TEST("xvda-1", -1);

    /********************************
     * IDE disks
     ********************************/

    DO_TEST("hd", -1);

    /* first numbered disk */
    DO_TEST("hda", 768);
    DO_TEST("hda1", 769);
    DO_TEST("hda63", 831);
    /* second numbered disk */
    DO_TEST("hdb", 832);
    DO_TEST("hdb1", 833);
    DO_TEST("hdb63", 895);
    /* third numbered disk */
    DO_TEST("hdc", 5632);
    DO_TEST("hdc1", 5633);
    DO_TEST("hdc63", 5695);
    /* fourth numbered disk */
    DO_TEST("hdd", 5696);
    DO_TEST("hdd1", 5697);
    DO_TEST("hdd63", 5759);
    /* last valid disk */
    DO_TEST("hdt", 23360);
    DO_TEST("hdt1", 23361);
    DO_TEST("hdt63", 23423);

    /* Disk letter to large */
    DO_TEST("hdu", -1);
    /* missing disk letter */
    DO_TEST("hd1", -1);
    /* partition too large */
    DO_TEST("hda64", -1);
    /* partition too small */
    DO_TEST("hda0", -1);



    /********************************
     * SCSI disks
     ********************************/

    DO_TEST("sd", -1);

    /* first valid disk */
    DO_TEST("sda", 2048);
    DO_TEST("sda1", 2049);
    DO_TEST("sda15", 2063);
    /* last valid disk of first SCSI major number */
    DO_TEST("sdp", 2288);
    DO_TEST("sdp1", 2289);
    DO_TEST("sdp15", 2303);
    /* first valid disk of second SCSI major number */
    DO_TEST("sdq", 16640);
    DO_TEST("sdq1", 16641);
    DO_TEST("sdq15", 16655);
    /* last valid single letter disk */
    DO_TEST("sdz", 16784);
    DO_TEST("sdz1", 16785);
    DO_TEST("sdz15", 16799);
    /* first valid dual letter disk */
    DO_TEST("sdaa", 16800);
    DO_TEST("sdaa1", 16801);
    DO_TEST("sdaa15", 16815);
    /* second valid dual letter disk */
    DO_TEST("sdab", 16816);
    DO_TEST("sdab1", 16817);
    DO_TEST("sdab15", 16831);
    /* first letter of second sequence of dual letter disk */
    DO_TEST("sdba", 17216);
    DO_TEST("sdba1", 17217);
    DO_TEST("sdba15", 17231);
    /* last valid dual letter disk */
    DO_TEST("sdiv", 34800);
    DO_TEST("sdiv1", 34801);
    DO_TEST("sdiv15", 34815);

    /* Disk letter too large */
    DO_TEST("sdix", -1);
    /* missing disk letter */
    DO_TEST("sd1", -1);
    /* partition too large */
    DO_TEST("sda16", -1);
    /* partition too small */
    DO_TEST("sda0", -1);


    /* Path stripping */
    DO_TEST("/dev", -1);
    DO_TEST("/dev/", -1);
    DO_TEST("/dev/xvd", -1);
    DO_TEST("/dev/xvda", 51712);
    DO_TEST("/dev/xvda1", 51713);
    DO_TEST("/dev/xvda15", 51727);

    return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

VIRT_TEST_MAIN(mymain)