~ubuntu-branches/ubuntu/quantal/libvirt/quantal

« back to all changes in this revision

Viewing changes to .pc/add-armhf-sysinfo-infomration.patch/src/util/sysinfo.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-07-19 14:54:47 UTC
  • Revision ID: package-import@ubuntu.com-20120719145447-ksf59r7lsc2df56l
Tags: 0.9.13-0ubuntu4
* debian/patches/add-armhf-sysinfo-infomration.patch:
  Provides cpuinfo for armhf cpus.
* debian/patches/add-armhf-cpuinfo-parser.patch:
  Fixes compile time warning about armhf cpus.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * sysinfo.c: get SMBIOS/sysinfo information from the host
 
3
 *
 
4
 * Copyright (C) 2010-2012 Red Hat, Inc.
 
5
 * Copyright (C) 2010 Daniel Veillard
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
20
 *
 
21
 * Author: Daniel Veillard <veillard@redhat.com>
 
22
 */
 
23
 
 
24
#include <config.h>
 
25
 
 
26
#include <sys/types.h>
 
27
#include <sys/wait.h>
 
28
#include <sys/stat.h>
 
29
#include <unistd.h>
 
30
#include <stdlib.h>
 
31
#include <stdio.h>
 
32
 
 
33
#include "virterror_internal.h"
 
34
#include "sysinfo.h"
 
35
#include "util.h"
 
36
#include "logging.h"
 
37
#include "memory.h"
 
38
#include "command.h"
 
39
 
 
40
#define VIR_FROM_THIS VIR_FROM_SYSINFO
 
41
 
 
42
#define virSmbiosReportError(code, ...)                               \
 
43
    virReportErrorHelper(VIR_FROM_SYSINFO, code, __FILE__,            \
 
44
                         __FUNCTION__, __LINE__, __VA_ARGS__)
 
45
 
 
46
#define SYSINFO_SMBIOS_DECODER "dmidecode"
 
47
#define SYSINFO "/proc/sysinfo"
 
48
#define CPUINFO "/proc/cpuinfo"
 
49
 
 
50
VIR_ENUM_IMPL(virSysinfo, VIR_SYSINFO_LAST,
 
51
              "smbios");
 
52
 
 
53
/**
 
54
 * virSysinfoDefFree:
 
55
 * @def: a sysinfo structure
 
56
 *
 
57
 * Free up the sysinfo structure
 
58
 */
 
59
 
 
60
void virSysinfoDefFree(virSysinfoDefPtr def)
 
61
{
 
62
    int i;
 
63
 
 
64
    if (def == NULL)
 
65
        return;
 
66
 
 
67
    VIR_FREE(def->bios_vendor);
 
68
    VIR_FREE(def->bios_version);
 
69
    VIR_FREE(def->bios_date);
 
70
    VIR_FREE(def->bios_release);
 
71
 
 
72
    VIR_FREE(def->system_manufacturer);
 
73
    VIR_FREE(def->system_product);
 
74
    VIR_FREE(def->system_version);
 
75
    VIR_FREE(def->system_serial);
 
76
    VIR_FREE(def->system_uuid);
 
77
    VIR_FREE(def->system_sku);
 
78
    VIR_FREE(def->system_family);
 
79
 
 
80
    for (i = 0;i < def->nprocessor;i++) {
 
81
        VIR_FREE(def->processor[i].processor_socket_destination);
 
82
        VIR_FREE(def->processor[i].processor_type);
 
83
        VIR_FREE(def->processor[i].processor_family);
 
84
        VIR_FREE(def->processor[i].processor_manufacturer);
 
85
        VIR_FREE(def->processor[i].processor_signature);
 
86
        VIR_FREE(def->processor[i].processor_version);
 
87
        VIR_FREE(def->processor[i].processor_external_clock);
 
88
        VIR_FREE(def->processor[i].processor_max_speed);
 
89
        VIR_FREE(def->processor[i].processor_status);
 
90
        VIR_FREE(def->processor[i].processor_serial_number);
 
91
        VIR_FREE(def->processor[i].processor_part_number);
 
92
    }
 
93
    VIR_FREE(def->processor);
 
94
    for (i = 0;i < def->nmemory;i++) {
 
95
        VIR_FREE(def->memory[i].memory_size);
 
96
        VIR_FREE(def->memory[i].memory_form_factor);
 
97
        VIR_FREE(def->memory[i].memory_locator);
 
98
        VIR_FREE(def->memory[i].memory_bank_locator);
 
99
        VIR_FREE(def->memory[i].memory_type);
 
100
        VIR_FREE(def->memory[i].memory_type_detail);
 
101
        VIR_FREE(def->memory[i].memory_speed);
 
102
        VIR_FREE(def->memory[i].memory_manufacturer);
 
103
        VIR_FREE(def->memory[i].memory_serial_number);
 
104
        VIR_FREE(def->memory[i].memory_part_number);
 
105
    }
 
106
    VIR_FREE(def->memory);
 
107
 
 
108
    VIR_FREE(def);
 
109
}
 
110
 
 
111
/**
 
112
 * virSysinfoRead:
 
113
 *
 
114
 * Tries to read the SMBIOS information from the current host
 
115
 *
 
116
 * Returns: a filled up sysinfo structure or NULL in case of error
 
117
 */
 
118
 
 
119
#if defined(__powerpc__)
 
120
static int
 
121
virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
 
122
{
 
123
    char *eol = NULL;
 
124
    const char *cur;
 
125
 
 
126
    if ((cur = strstr(base, "platform")) == NULL)
 
127
        return 0;
 
128
 
 
129
    base = cur;
 
130
    /* Account for format 'platform    : XXXX'*/
 
131
    cur = strchr(cur, ':') + 1;
 
132
    eol = strchr(cur, '\n');
 
133
    virSkipSpaces(&cur);
 
134
    if (eol &&
 
135
       ((ret->system_family = strndup(cur, eol - cur)) == NULL))
 
136
         goto no_memory;
 
137
 
 
138
    if ((cur = strstr(base, "model")) != NULL) {
 
139
        cur = strchr(cur, ':') + 1;
 
140
        eol = strchr(cur, '\n');
 
141
        virSkipSpaces(&cur);
 
142
        if (eol && ((ret->system_serial = strndup(cur, eol - cur))
 
143
                                                           == NULL))
 
144
            goto no_memory;
 
145
    }
 
146
 
 
147
    if ((cur = strstr(base, "machine")) != NULL) {
 
148
        cur = strchr(cur, ':') + 1;
 
149
        eol = strchr(cur, '\n');
 
150
        virSkipSpaces(&cur);
 
151
        if (eol && ((ret->system_version = strndup(cur, eol - cur))
 
152
                                                            == NULL))
 
153
            goto no_memory;
 
154
    }
 
155
 
 
156
    return 0;
 
157
 
 
158
no_memory:
 
159
    return -1;
 
160
}
 
161
 
 
162
static int
 
163
virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret)
 
164
{
 
165
    const char *cur;
 
166
    char *eol, *tmp_base;
 
167
    virSysinfoProcessorDefPtr processor;
 
168
 
 
169
    while((tmp_base = strstr(base, "processor")) != NULL) {
 
170
        base = tmp_base;
 
171
        eol = strchr(base, '\n');
 
172
        cur = strchr(base, ':') + 1;
 
173
 
 
174
        if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) {
 
175
            goto no_memory;
 
176
        }
 
177
        processor = &ret->processor[ret->nprocessor - 1];
 
178
 
 
179
        virSkipSpaces(&cur);
 
180
        if (eol &&
 
181
            ((processor->processor_socket_destination = strndup
 
182
                                     (cur, eol - cur)) == NULL))
 
183
            goto no_memory;
 
184
 
 
185
        if ((cur = strstr(base, "cpu")) != NULL) {
 
186
            cur = strchr(cur, ':') + 1;
 
187
            eol = strchr(cur, '\n');
 
188
            virSkipSpaces(&cur);
 
189
            if (eol &&
 
190
               ((processor->processor_type = strndup(cur, eol - cur))
 
191
                                                             == NULL))
 
192
                goto no_memory;
 
193
        }
 
194
 
 
195
        if ((cur = strstr(base, "revision")) != NULL) {
 
196
            cur = strchr(cur, ':') + 1;
 
197
            eol = strchr(cur, '\n');
 
198
            virSkipSpaces(&cur);
 
199
            if (eol &&
 
200
               ((processor->processor_version = strndup(cur, eol - cur))
 
201
                                                                == NULL))
 
202
                goto no_memory;
 
203
        }
 
204
 
 
205
        base = cur;
 
206
    }
 
207
 
 
208
    return 0;
 
209
 
 
210
no_memory:
 
211
    return -1;
 
212
}
 
213
 
 
214
/* virSysinfoRead for PowerPC
 
215
 * Gathers sysinfo data from /proc/cpuinfo */
 
216
virSysinfoDefPtr
 
217
virSysinfoRead(void) {
 
218
    virSysinfoDefPtr ret = NULL;
 
219
    char *outbuf = NULL;
 
220
 
 
221
    if (VIR_ALLOC(ret) < 0)
 
222
        goto no_memory;
 
223
 
 
224
    if(virFileReadAll(CPUINFO, 2048, &outbuf) < 0) {
 
225
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
 
226
                             _("Failed to open %s"), CPUINFO);
 
227
        return NULL;
 
228
    }
 
229
 
 
230
    ret->nprocessor = 0;
 
231
    ret->processor = NULL;
 
232
    if (virSysinfoParseProcessor(outbuf, ret) < 0)
 
233
        goto no_memory;
 
234
 
 
235
    if (virSysinfoParseSystem(outbuf, ret) < 0)
 
236
        goto no_memory;
 
237
 
 
238
    return ret;
 
239
 
 
240
no_memory:
 
241
    VIR_FREE(outbuf);
 
242
    return NULL;
 
243
}
 
244
 
 
245
#elif defined(__s390__) || defined(__s390x__)
 
246
 
 
247
static int
 
248
virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
 
249
{
 
250
    char *cur, *eol = NULL;
 
251
    const char *property;
 
252
 
 
253
    /* Return if Manufacturer field is not found */
 
254
    if ((cur = strstr(base, "Manufacturer")) == NULL)
 
255
        return 0;
 
256
 
 
257
    base = cur;
 
258
    if ((cur = strstr(base, "Manufacturer")) != NULL) {
 
259
        cur = strchr(cur, ':') + 1;
 
260
        eol = strchr(cur, '\n');
 
261
        virSkipSpacesBackwards(cur, &eol);
 
262
        if ((eol) && ((property = strndup(cur, eol - cur)) == NULL))
 
263
            goto no_memory;
 
264
        virSkipSpaces(&property);
 
265
        ret->system_manufacturer = (char *) property;
 
266
    }
 
267
    if ((cur = strstr(base, "Type")) != NULL) {
 
268
        cur = strchr(cur, ':') + 1;
 
269
        eol = strchr(cur, '\n');
 
270
        virSkipSpacesBackwards(cur, &eol);
 
271
        if ((eol) && ((property = strndup(cur, eol - cur)) == NULL))
 
272
            goto no_memory;
 
273
        virSkipSpaces(&property);
 
274
        ret->system_family = (char *) property;
 
275
    }
 
276
    if ((cur = strstr(base, "Sequence Code")) != NULL) {
 
277
        cur = strchr(cur, ':') + 1;
 
278
        eol = strchr(cur, '\n');
 
279
        virSkipSpacesBackwards(cur, &eol);
 
280
        if ((eol) && ((property = strndup(cur, eol - cur)) == NULL))
 
281
            goto no_memory;
 
282
        virSkipSpaces(&property);
 
283
        ret->system_serial = (char *) property;
 
284
    }
 
285
 
 
286
    return 0;
 
287
 
 
288
no_memory:
 
289
    return -1;
 
290
}
 
291
 
 
292
static int
 
293
virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret)
 
294
{
 
295
    char *cur, *eol, *tmp_base;
 
296
    char *manufacturer;
 
297
    const char *tmp;
 
298
    virSysinfoProcessorDefPtr processor;
 
299
 
 
300
    if ((cur = strstr(base, "vendor_id")) != NULL) {
 
301
        cur = strchr(cur, ':') + 1;
 
302
        eol = strchr(cur, '\n');
 
303
        virSkipSpacesBackwards(cur, &eol);
 
304
        if ((eol) && ((tmp = strndup(cur, eol - cur)) == NULL))
 
305
            goto no_memory;
 
306
        virSkipSpaces(&tmp);
 
307
        manufacturer = (char *) tmp;
 
308
    }
 
309
 
 
310
    /* Find processor N: line and gather the processor manufacturer, version,
 
311
     * serial number, and family */
 
312
    while ((tmp_base = strstr(base, "processor ")) != NULL) {
 
313
        base = tmp_base;
 
314
        eol = strchr(base, '\n');
 
315
        cur = strchr(base, ':') + 1;
 
316
 
 
317
        if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) {
 
318
            goto no_memory;
 
319
        }
 
320
 
 
321
        processor = &ret->processor[ret->nprocessor - 1];
 
322
 
 
323
        /* Set the processor manufacturer */
 
324
        processor->processor_manufacturer = manufacturer;
 
325
 
 
326
        if ((cur = strstr(base, "version =")) != NULL) {
 
327
            cur += sizeof("version =");
 
328
            eol = strchr(cur, ',');
 
329
            if ((eol) &&
 
330
                ((processor->processor_version = strndup(cur, eol - cur)) == NULL))
 
331
                goto no_memory;
 
332
        }
 
333
        if ((cur = strstr(base, "identification =")) != NULL) {
 
334
            cur += sizeof("identification =");
 
335
            eol = strchr(cur, ',');
 
336
            if ((eol) &&
 
337
                ((processor->processor_serial_number = strndup(cur, eol - cur)) == NULL))
 
338
                goto no_memory;
 
339
        }
 
340
        if ((cur = strstr(base, "machine =")) != NULL) {
 
341
            cur += sizeof("machine =");
 
342
            eol = strchr(cur, '\n');
 
343
            if ((eol) &&
 
344
                ((processor->processor_family = strndup(cur, eol - cur)) == NULL))
 
345
                goto no_memory;
 
346
        }
 
347
 
 
348
        base = cur;
 
349
    }
 
350
 
 
351
    return 0;
 
352
 
 
353
no_memory:
 
354
    return -1;
 
355
}
 
356
 
 
357
/* virSysinfoRead for s390x
 
358
 * Gathers sysinfo data from /proc/sysinfo and /proc/cpuinfo */
 
359
virSysinfoDefPtr
 
360
virSysinfoRead(void) {
 
361
    virSysinfoDefPtr ret = NULL;
 
362
    char *outbuf = NULL;
 
363
 
 
364
    if (VIR_ALLOC(ret) < 0)
 
365
        goto no_memory;
 
366
 
 
367
    /* Gather info from /proc/cpuinfo */
 
368
    if (virFileReadAll(CPUINFO, 2048, &outbuf) < 0) {
 
369
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
 
370
                             _("Failed to open %s"), CPUINFO);
 
371
        return NULL;
 
372
    }
 
373
 
 
374
    ret->nprocessor = 0;
 
375
    ret->processor = NULL;
 
376
    if (virSysinfoParseProcessor(outbuf, ret) < 0)
 
377
        goto no_memory;
 
378
 
 
379
    /* Free buffer before reading next file */
 
380
    VIR_FREE(outbuf);
 
381
 
 
382
    /* Gather info from /proc/sysinfo */
 
383
    if (virFileReadAll(SYSINFO, 4096, &outbuf) < 0) {
 
384
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
 
385
                             _("Failed to open %s"), SYSINFO);
 
386
        return NULL;
 
387
    }
 
388
 
 
389
    if (virSysinfoParseSystem(outbuf, ret) < 0)
 
390
        goto no_memory;
 
391
 
 
392
    return ret;
 
393
 
 
394
no_memory:
 
395
    VIR_FREE(outbuf);
 
396
    return NULL;
 
397
}
 
398
 
 
399
#elif defined(WIN32) || \
 
400
    !(defined(__x86_64__) || \
 
401
      defined(__i386__) ||   \
 
402
      defined(__amd64__) || \
 
403
      defined(__powerpc__))
 
404
virSysinfoDefPtr
 
405
virSysinfoRead(void) {
 
406
    /*
 
407
     * this can probably be extracted from Windows using API or registry
 
408
     * http://www.microsoft.com/whdc/system/platform/firmware/SMBIOS.mspx
 
409
     */
 
410
    virReportSystemError(ENOSYS, "%s",
 
411
                 _("Host sysinfo extraction not supported on this platform"));
 
412
    return NULL;
 
413
}
 
414
 
 
415
#else /* !WIN32 && x86 */
 
416
 
 
417
static int
 
418
virSysinfoParseBIOS(const char *base, virSysinfoDefPtr ret)
 
419
{
 
420
    const char *cur, *eol = NULL;
 
421
 
 
422
    if ((cur = strstr(base, "BIOS Information")) == NULL)
 
423
        return 0;
 
424
 
 
425
    base = cur;
 
426
    if ((cur = strstr(base, "Vendor: ")) != NULL) {
 
427
        cur += 8;
 
428
        eol = strchr(cur, '\n');
 
429
        if ((eol) && ((ret->bios_vendor = strndup(cur, eol - cur)) == NULL))
 
430
            goto no_memory;
 
431
    }
 
432
    if ((cur = strstr(base, "Version: ")) != NULL) {
 
433
        cur += 9;
 
434
        eol = strchr(cur, '\n');
 
435
        if ((eol) && ((ret->bios_version = strndup(cur, eol - cur)) == NULL))
 
436
            goto no_memory;
 
437
    }
 
438
    if ((cur = strstr(base, "Release Date: ")) != NULL) {
 
439
        cur += 14;
 
440
        eol = strchr(cur, '\n');
 
441
        if ((eol) && ((ret->bios_date = strndup(cur, eol - cur)) == NULL))
 
442
            goto no_memory;
 
443
    }
 
444
    if ((cur = strstr(base, "BIOS Revision: ")) != NULL) {
 
445
        cur += 15;
 
446
        eol = strchr(cur, '\n');
 
447
        if ((eol) && ((ret->bios_release = strndup(cur, eol - cur)) == NULL))
 
448
            goto no_memory;
 
449
    }
 
450
 
 
451
    return 0;
 
452
 
 
453
no_memory:
 
454
    return -1;
 
455
}
 
456
 
 
457
static int
 
458
virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
 
459
{
 
460
    const char *cur, *eol = NULL;
 
461
 
 
462
    if ((cur = strstr(base, "System Information")) == NULL)
 
463
        return 0;
 
464
 
 
465
    base = cur;
 
466
    if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
 
467
        cur += 14;
 
468
        eol = strchr(cur, '\n');
 
469
        if ((eol) &&
 
470
            ((ret->system_manufacturer = strndup(cur, eol - cur)) == NULL))
 
471
            goto no_memory;
 
472
    }
 
473
    if ((cur = strstr(base, "Product Name: ")) != NULL) {
 
474
        cur += 14;
 
475
        eol = strchr(cur, '\n');
 
476
        if ((eol) && ((ret->system_product = strndup(cur, eol - cur)) == NULL))
 
477
            goto no_memory;
 
478
    }
 
479
    if ((cur = strstr(base, "Version: ")) != NULL) {
 
480
        cur += 9;
 
481
        eol = strchr(cur, '\n');
 
482
        if ((eol) && ((ret->system_version = strndup(cur, eol - cur)) == NULL))
 
483
            goto no_memory;
 
484
    }
 
485
    if ((cur = strstr(base, "Serial Number: ")) != NULL) {
 
486
        cur += 15;
 
487
        eol = strchr(cur, '\n');
 
488
        if ((eol) && ((ret->system_serial = strndup(cur, eol - cur)) == NULL))
 
489
            goto no_memory;
 
490
    }
 
491
    if ((cur = strstr(base, "UUID: ")) != NULL) {
 
492
        cur += 6;
 
493
        eol = strchr(cur, '\n');
 
494
        if ((eol) && ((ret->system_uuid = strndup(cur, eol - cur)) == NULL))
 
495
            goto no_memory;
 
496
    }
 
497
    if ((cur = strstr(base, "SKU Number: ")) != NULL) {
 
498
        cur += 12;
 
499
        eol = strchr(cur, '\n');
 
500
        if ((eol) && ((ret->system_sku = strndup(cur, eol - cur)) == NULL))
 
501
            goto no_memory;
 
502
    }
 
503
    if ((cur = strstr(base, "Family: ")) != NULL) {
 
504
        cur += 8;
 
505
        eol = strchr(cur, '\n');
 
506
        if ((eol) && ((ret->system_family = strndup(cur, eol - cur)) == NULL))
 
507
            goto no_memory;
 
508
    }
 
509
 
 
510
    return 0;
 
511
 
 
512
no_memory:
 
513
    return -1;
 
514
}
 
515
 
 
516
static int
 
517
virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret)
 
518
{
 
519
    const char *cur, *tmp_base;
 
520
    char *eol;
 
521
    virSysinfoProcessorDefPtr processor;
 
522
 
 
523
    while((tmp_base = strstr(base, "Processor Information")) != NULL) {
 
524
        base = tmp_base;
 
525
        eol = NULL;
 
526
 
 
527
        if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) {
 
528
            goto no_memory;
 
529
        }
 
530
        processor = &ret->processor[ret->nprocessor - 1];
 
531
 
 
532
        if ((cur = strstr(base, "Socket Designation: ")) != NULL) {
 
533
            cur += 20;
 
534
            eol = strchr(cur, '\n');
 
535
            virSkipSpacesBackwards(cur, &eol);
 
536
            if ((eol) &&
 
537
                ((processor->processor_socket_destination
 
538
                  = strndup(cur, eol - cur)) == NULL))
 
539
                goto no_memory;
 
540
        }
 
541
        if ((cur = strstr(base, "Type: ")) != NULL) {
 
542
            cur += 6;
 
543
            eol = strchr(cur, '\n');
 
544
            virSkipSpacesBackwards(cur, &eol);
 
545
            if ((eol) &&
 
546
                ((processor->processor_type = strndup(cur, eol - cur)) == NULL))
 
547
                goto no_memory;
 
548
        }
 
549
        if ((cur = strstr(base, "Family: ")) != NULL) {
 
550
            cur += 8;
 
551
            eol = strchr(cur, '\n');
 
552
            virSkipSpacesBackwards(cur, &eol);
 
553
            if ((eol) &&
 
554
                ((processor->processor_family = strndup(cur,
 
555
                                                        eol - cur)) == NULL))
 
556
                goto no_memory;
 
557
        }
 
558
        if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
 
559
            cur += 14;
 
560
            eol = strchr(cur, '\n');
 
561
            virSkipSpacesBackwards(cur, &eol);
 
562
            if ((eol) &&
 
563
                ((processor->processor_manufacturer
 
564
                  = strndup(cur, eol - cur)) == NULL))
 
565
                goto no_memory;
 
566
        }
 
567
        if ((cur = strstr(base, "Signature: ")) != NULL) {
 
568
            cur += 11;
 
569
            eol = strchr(cur, '\n');
 
570
            virSkipSpacesBackwards(cur, &eol);
 
571
            if ((eol) &&
 
572
                ((processor->processor_signature
 
573
                  = strndup(cur, eol - cur)) == NULL))
 
574
                goto no_memory;
 
575
        }
 
576
        if ((cur = strstr(base, "Version: ")) != NULL) {
 
577
            cur += 9;
 
578
            eol = strchr(cur, '\n');
 
579
            virSkipSpacesBackwards(cur, &eol);
 
580
            if ((eol) &&
 
581
                ((processor->processor_version = strndup(cur,
 
582
                                                         eol - cur)) == NULL))
 
583
                goto no_memory;
 
584
        }
 
585
        if ((cur = strstr(base, "External Clock: ")) != NULL) {
 
586
            cur += 16;
 
587
            eol = strchr(cur, '\n');
 
588
            virSkipSpacesBackwards(cur, &eol);
 
589
            if ((eol) &&
 
590
                ((processor->processor_external_clock
 
591
                  = strndup(cur, eol - cur)) == NULL))
 
592
                goto no_memory;
 
593
        }
 
594
        if ((cur = strstr(base, "Max Speed: ")) != NULL) {
 
595
            cur += 11;
 
596
            eol = strchr(cur, '\n');
 
597
            virSkipSpacesBackwards(cur, &eol);
 
598
            if ((eol) &&
 
599
                ((processor->processor_max_speed
 
600
                  = strndup(cur, eol - cur)) == NULL))
 
601
                goto no_memory;
 
602
        }
 
603
        if ((cur = strstr(base, "Status: ")) != NULL) {
 
604
            cur += 8;
 
605
            eol = strchr(cur, '\n');
 
606
            virSkipSpacesBackwards(cur, &eol);
 
607
            if ((eol) &&
 
608
                ((processor->processor_status = strndup(cur,
 
609
                                                        eol - cur)) == NULL))
 
610
                goto no_memory;
 
611
        }
 
612
        if ((cur = strstr(base, "Serial Number: ")) != NULL) {
 
613
            cur += 15;
 
614
            eol = strchr(cur, '\n');
 
615
            virSkipSpacesBackwards(cur, &eol);
 
616
            if ((eol) &&
 
617
                ((processor->processor_serial_number
 
618
                  = strndup(cur, eol - cur)) == NULL))
 
619
                goto no_memory;
 
620
        }
 
621
        if ((cur = strstr(base, "Part Number: ")) != NULL) {
 
622
            cur += 13;
 
623
            eol = strchr(cur, '\n');
 
624
            virSkipSpacesBackwards(cur, &eol);
 
625
            if ((eol) &&
 
626
                ((processor->processor_part_number
 
627
                  = strndup(cur, eol - cur)) == NULL))
 
628
                goto no_memory;
 
629
        }
 
630
 
 
631
        base += strlen("Processor Information");
 
632
    }
 
633
 
 
634
    return 0;
 
635
 
 
636
no_memory:
 
637
    return -1;
 
638
}
 
639
 
 
640
static int
 
641
virSysinfoParseMemory(const char *base, virSysinfoDefPtr ret)
 
642
{
 
643
    const char *cur, *tmp_base;
 
644
    char *eol;
 
645
    virSysinfoMemoryDefPtr memory;
 
646
 
 
647
    while ((tmp_base = strstr(base, "Memory Device")) != NULL) {
 
648
        base = tmp_base;
 
649
        eol = NULL;
 
650
 
 
651
        if (VIR_EXPAND_N(ret->memory, ret->nmemory, 1) < 0) {
 
652
            goto no_memory;
 
653
        }
 
654
        memory = &ret->memory[ret->nmemory - 1];
 
655
 
 
656
        if ((cur = strstr(base, "Size: ")) != NULL) {
 
657
            cur += 6;
 
658
            eol = strchr(cur, '\n');
 
659
            if (STREQLEN(cur, "No Module Installed", eol - cur))
 
660
                goto next;
 
661
 
 
662
            virSkipSpacesBackwards(cur, &eol);
 
663
            if ((eol) &&
 
664
                ((memory->memory_size = strndup(cur, eol - cur)) == NULL))
 
665
                goto no_memory;
 
666
        }
 
667
        if ((cur = strstr(base, "Form Factor: ")) != NULL) {
 
668
            cur += 13;
 
669
            eol = strchr(cur, '\n');
 
670
            virSkipSpacesBackwards(cur, &eol);
 
671
            if ((eol) &&
 
672
                ((memory->memory_form_factor = strndup(cur,
 
673
                                                       eol - cur)) == NULL))
 
674
                goto no_memory;
 
675
        }
 
676
        if ((cur = strstr(base, "Locator: ")) != NULL) {
 
677
            cur += 9;
 
678
            eol = strchr(cur, '\n');
 
679
            virSkipSpacesBackwards(cur, &eol);
 
680
            if ((eol) &&
 
681
                ((memory->memory_locator = strndup(cur, eol - cur)) == NULL))
 
682
                goto no_memory;
 
683
        }
 
684
        if ((cur = strstr(base, "Bank Locator: ")) != NULL) {
 
685
            cur += 14;
 
686
            eol = strchr(cur, '\n');
 
687
            virSkipSpacesBackwards(cur, &eol);
 
688
            if ((eol) &&
 
689
                ((memory->memory_bank_locator = strndup(cur,
 
690
                                                        eol - cur)) == NULL))
 
691
                goto no_memory;
 
692
        }
 
693
        if ((cur = strstr(base, "Type: ")) != NULL) {
 
694
            cur += 6;
 
695
            eol = strchr(cur, '\n');
 
696
            virSkipSpacesBackwards(cur, &eol);
 
697
            if ((eol) &&
 
698
                ((memory->memory_type = strndup(cur, eol - cur)) == NULL))
 
699
                goto no_memory;
 
700
        }
 
701
        if ((cur = strstr(base, "Type Detail: ")) != NULL) {
 
702
            cur += 13;
 
703
            eol = strchr(cur, '\n');
 
704
            virSkipSpacesBackwards(cur, &eol);
 
705
            if ((eol) &&
 
706
                ((memory->memory_type_detail = strndup(cur,
 
707
                                                       eol - cur)) == NULL))
 
708
                goto no_memory;
 
709
        }
 
710
        if ((cur = strstr(base, "Speed: ")) != NULL) {
 
711
            cur += 7;
 
712
            eol = strchr(cur, '\n');
 
713
            virSkipSpacesBackwards(cur, &eol);
 
714
            if ((eol) &&
 
715
                ((memory->memory_speed = strndup(cur, eol - cur)) == NULL))
 
716
                goto no_memory;
 
717
        }
 
718
        if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
 
719
            cur += 14;
 
720
            eol = strchr(cur, '\n');
 
721
            virSkipSpacesBackwards(cur, &eol);
 
722
            if ((eol) &&
 
723
                ((memory->memory_manufacturer = strndup(cur,
 
724
                                                        eol - cur)) == NULL))
 
725
                goto no_memory;
 
726
        }
 
727
        if ((cur = strstr(base, "Serial Number: ")) != NULL) {
 
728
            cur += 15;
 
729
            eol = strchr(cur, '\n');
 
730
            virSkipSpacesBackwards(cur, &eol);
 
731
            if ((eol) &&
 
732
                ((memory->memory_serial_number = strndup(cur,
 
733
                                                         eol - cur)) == NULL))
 
734
                goto no_memory;
 
735
        }
 
736
        if ((cur = strstr(base, "Part Number: ")) != NULL) {
 
737
            cur += 13;
 
738
            eol = strchr(cur, '\n');
 
739
            virSkipSpacesBackwards(cur, &eol);
 
740
            if ((eol) &&
 
741
                ((memory->memory_part_number = strndup(cur,
 
742
                                                       eol - cur)) == NULL))
 
743
                goto no_memory;
 
744
        }
 
745
 
 
746
    next:
 
747
        base += strlen("Memory Device");
 
748
    }
 
749
 
 
750
    return 0;
 
751
 
 
752
no_memory:
 
753
    return -1;
 
754
}
 
755
 
 
756
virSysinfoDefPtr
 
757
virSysinfoRead(void) {
 
758
    char *path;
 
759
    virSysinfoDefPtr ret = NULL;
 
760
    char *outbuf = NULL;
 
761
    virCommandPtr cmd;
 
762
 
 
763
    path = virFindFileInPath(SYSINFO_SMBIOS_DECODER);
 
764
    if (path == NULL) {
 
765
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
 
766
                             _("Failed to find path for %s binary"),
 
767
                             SYSINFO_SMBIOS_DECODER);
 
768
        return NULL;
 
769
    }
 
770
 
 
771
    cmd = virCommandNewArgList(path, "-q", "-t", "0,1,4,17", NULL);
 
772
    VIR_FREE(path);
 
773
    virCommandSetOutputBuffer(cmd, &outbuf);
 
774
    if (virCommandRun(cmd, NULL) < 0) {
 
775
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
 
776
                             _("Failed to execute command %s"),
 
777
                             path);
 
778
        goto cleanup;
 
779
    }
 
780
 
 
781
    if (VIR_ALLOC(ret) < 0)
 
782
        goto no_memory;
 
783
 
 
784
    ret->type = VIR_SYSINFO_SMBIOS;
 
785
 
 
786
    if (virSysinfoParseBIOS(outbuf, ret) < 0)
 
787
        goto no_memory;
 
788
 
 
789
    if (virSysinfoParseSystem(outbuf, ret) < 0)
 
790
        goto no_memory;
 
791
 
 
792
    ret->nprocessor = 0;
 
793
    ret->processor = NULL;
 
794
    if (virSysinfoParseProcessor(outbuf, ret) < 0)
 
795
        goto no_memory;
 
796
 
 
797
    ret->nmemory = 0;
 
798
    ret->memory = NULL;
 
799
    if (virSysinfoParseMemory(outbuf, ret) < 0)
 
800
        goto no_memory;
 
801
 
 
802
cleanup:
 
803
    VIR_FREE(outbuf);
 
804
    virCommandFree(cmd);
 
805
 
 
806
    return ret;
 
807
 
 
808
no_memory:
 
809
    virReportOOMError();
 
810
 
 
811
    virSysinfoDefFree(ret);
 
812
    ret = NULL;
 
813
    goto cleanup;
 
814
}
 
815
#endif /* !WIN32 && x86 */
 
816
 
 
817
static void
 
818
virSysinfoBIOSFormat(virBufferPtr buf, virSysinfoDefPtr def)
 
819
{
 
820
    if (!def->bios_vendor && !def->bios_version &&
 
821
        !def->bios_date && !def->bios_release)
 
822
        return;
 
823
 
 
824
    virBufferAddLit(buf, "  <bios>\n");
 
825
    virBufferEscapeString(buf, "    <entry name='vendor'>%s</entry>\n",
 
826
                          def->bios_vendor);
 
827
    virBufferEscapeString(buf, "    <entry name='version'>%s</entry>\n",
 
828
                          def->bios_version);
 
829
    virBufferEscapeString(buf, "    <entry name='date'>%s</entry>\n",
 
830
                          def->bios_date);
 
831
    virBufferEscapeString(buf, "    <entry name='release'>%s</entry>\n",
 
832
                          def->bios_release);
 
833
    virBufferAddLit(buf, "  </bios>\n");
 
834
}
 
835
 
 
836
static void
 
837
virSysinfoSystemFormat(virBufferPtr buf, virSysinfoDefPtr def)
 
838
{
 
839
    if (!def->system_manufacturer && !def->system_product &&
 
840
        !def->system_version && !def->system_serial &&
 
841
        !def->system_uuid && !def->system_sku && !def->system_family)
 
842
        return;
 
843
 
 
844
    virBufferAddLit(buf, "  <system>\n");
 
845
    virBufferEscapeString(buf, "    <entry name='manufacturer'>%s</entry>\n",
 
846
                          def->system_manufacturer);
 
847
    virBufferEscapeString(buf, "    <entry name='product'>%s</entry>\n",
 
848
                          def->system_product);
 
849
    virBufferEscapeString(buf, "    <entry name='version'>%s</entry>\n",
 
850
                          def->system_version);
 
851
    virBufferEscapeString(buf, "    <entry name='serial'>%s</entry>\n",
 
852
                          def->system_serial);
 
853
    virBufferEscapeString(buf, "    <entry name='uuid'>%s</entry>\n",
 
854
                          def->system_uuid);
 
855
    virBufferEscapeString(buf, "    <entry name='sku'>%s</entry>\n",
 
856
                          def->system_sku);
 
857
    virBufferEscapeString(buf, "    <entry name='family'>%s</entry>\n",
 
858
                          def->system_family);
 
859
    virBufferAddLit(buf, "  </system>\n");
 
860
}
 
861
 
 
862
static void
 
863
virSysinfoProcessorFormat(virBufferPtr buf, virSysinfoDefPtr def)
 
864
{
 
865
    int i;
 
866
    virSysinfoProcessorDefPtr processor;
 
867
 
 
868
    for (i = 0; i < def->nprocessor; i++) {
 
869
        processor = &def->processor[i];
 
870
 
 
871
        if (!processor->processor_socket_destination &&
 
872
            !processor->processor_type &&
 
873
            !processor->processor_family &&
 
874
            !processor->processor_manufacturer &&
 
875
            !processor->processor_signature &&
 
876
            !processor->processor_version &&
 
877
            !processor->processor_external_clock &&
 
878
            !processor->processor_max_speed &&
 
879
            !processor->processor_status &&
 
880
            !processor->processor_serial_number &&
 
881
            !processor->processor_part_number)
 
882
            continue;
 
883
 
 
884
        virBufferAddLit(buf, "  <processor>\n");
 
885
        virBufferAdjustIndent(buf, 4);
 
886
        virBufferEscapeString(buf,
 
887
                              "<entry name='socket_destination'>%s</entry>\n",
 
888
                              processor->processor_socket_destination);
 
889
        virBufferEscapeString(buf, "<entry name='type'>%s</entry>\n",
 
890
                              processor->processor_type);
 
891
        virBufferEscapeString(buf, "<entry name='family'>%s</entry>\n",
 
892
                              processor->processor_family);
 
893
        virBufferEscapeString(buf, "<entry name='manufacturer'>%s</entry>\n",
 
894
                              processor->processor_manufacturer);
 
895
        virBufferEscapeString(buf, "<entry name='signature'>%s</entry>\n",
 
896
                              processor->processor_signature);
 
897
        virBufferEscapeString(buf, "<entry name='version'>%s</entry>\n",
 
898
                              processor->processor_version);
 
899
        virBufferEscapeString(buf, "<entry name='external_clock'>%s</entry>\n",
 
900
                              processor->processor_external_clock);
 
901
        virBufferEscapeString(buf, "<entry name='max_speed'>%s</entry>\n",
 
902
                              processor->processor_max_speed);
 
903
        virBufferEscapeString(buf, "<entry name='status'>%s</entry>\n",
 
904
                              processor->processor_status);
 
905
        virBufferEscapeString(buf, "<entry name='serial_number'>%s</entry>\n",
 
906
                              processor->processor_serial_number);
 
907
        virBufferEscapeString(buf, "<entry name='part_number'>%s</entry>\n",
 
908
                              processor->processor_part_number);
 
909
        virBufferAdjustIndent(buf, -4);
 
910
        virBufferAddLit(buf, "  </processor>\n");
 
911
    }
 
912
}
 
913
 
 
914
static void
 
915
virSysinfoMemoryFormat(virBufferPtr buf, virSysinfoDefPtr def)
 
916
{
 
917
    int i;
 
918
    virSysinfoMemoryDefPtr memory;
 
919
 
 
920
    for (i = 0; i < def->nmemory; i++) {
 
921
        memory = &def->memory[i];
 
922
 
 
923
        if (!memory->memory_size &&
 
924
            !memory->memory_form_factor &&
 
925
            !memory->memory_locator &&
 
926
            !memory->memory_bank_locator &&
 
927
            !memory->memory_type &&
 
928
            !memory->memory_type_detail &&
 
929
            !memory->memory_speed &&
 
930
            !memory->memory_manufacturer &&
 
931
            !memory->memory_serial_number &&
 
932
            !memory->memory_part_number)
 
933
            continue;
 
934
 
 
935
        virBufferAddLit(buf, "  <memory_device>\n");
 
936
        virBufferEscapeString(buf, "    <entry name='size'>%s</entry>\n",
 
937
                              memory->memory_size);
 
938
        virBufferEscapeString(buf,
 
939
                              "    <entry name='form_factor'>%s</entry>\n",
 
940
                              memory->memory_form_factor);
 
941
        virBufferEscapeString(buf, "    <entry name='locator'>%s</entry>\n",
 
942
                              memory->memory_locator);
 
943
        virBufferEscapeString(buf,
 
944
                              "    <entry name='bank_locator'>%s</entry>\n",
 
945
                              memory->memory_bank_locator);
 
946
        virBufferEscapeString(buf, "    <entry name='type'>%s</entry>\n",
 
947
                              memory->memory_type);
 
948
        virBufferEscapeString(buf,
 
949
                              "    <entry name='type_detail'>%s</entry>\n",
 
950
                              memory->memory_type_detail);
 
951
        virBufferEscapeString(buf, "    <entry name='speed'>%s</entry>\n",
 
952
                              memory->memory_speed);
 
953
        virBufferEscapeString(buf,
 
954
                              "    <entry name='manufacturer'>%s</entry>\n",
 
955
                              memory->memory_manufacturer);
 
956
        virBufferEscapeString(buf,
 
957
                              "    <entry name='serial_number'>%s</entry>\n",
 
958
                              memory->memory_serial_number);
 
959
        virBufferEscapeString(buf,
 
960
                              "    <entry name='part_number'>%s</entry>\n",
 
961
                              memory->memory_part_number);
 
962
        virBufferAddLit(buf, "  </memory_device>\n");
 
963
    }
 
964
}
 
965
 
 
966
/**
 
967
 * virSysinfoFormat:
 
968
 * @buf: buffer to append output to (may use auto-indentation)
 
969
 * @def: structure to convert to xml string
 
970
 *
 
971
 * Returns 0 on success, -1 on failure after generating an error message.
 
972
 */
 
973
int
 
974
virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
 
975
{
 
976
    const char *type = virSysinfoTypeToString(def->type);
 
977
 
 
978
    if (!type) {
 
979
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
 
980
                             _("unexpected sysinfo type model %d"),
 
981
                             def->type);
 
982
        virBufferFreeAndReset(buf);
 
983
        return -1;
 
984
    }
 
985
 
 
986
    virBufferAsprintf(buf, "<sysinfo type='%s'>\n", type);
 
987
 
 
988
    virSysinfoBIOSFormat(buf, def);
 
989
    virSysinfoSystemFormat(buf, def);
 
990
    virSysinfoProcessorFormat(buf, def);
 
991
    virSysinfoMemoryFormat(buf, def);
 
992
 
 
993
    virBufferAddLit(buf, "</sysinfo>\n");
 
994
 
 
995
    if (virBufferError(buf)) {
 
996
        virReportOOMError();
 
997
        return -1;
 
998
    }
 
999
 
 
1000
    return 0;
 
1001
}
 
1002
 
 
1003
bool virSysinfoIsEqual(virSysinfoDefPtr src,
 
1004
                       virSysinfoDefPtr dst)
 
1005
{
 
1006
    bool identical = false;
 
1007
 
 
1008
    if (!src && !dst)
 
1009
        return true;
 
1010
 
 
1011
    if ((src && !dst) || (!src && dst)) {
 
1012
        virSmbiosReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 
1013
                             _("Target sysinfo does not match source"));
 
1014
        goto cleanup;
 
1015
    }
 
1016
 
 
1017
    if (src->type != dst->type) {
 
1018
        virSmbiosReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
1019
                             _("Target sysinfo %s does not match source %s"),
 
1020
                             virSysinfoTypeToString(dst->type),
 
1021
                             virSysinfoTypeToString(src->type));
 
1022
        goto cleanup;
 
1023
    }
 
1024
 
 
1025
#define CHECK_FIELD(name, desc)                                         \
 
1026
    do {                                                                \
 
1027
        if (STRNEQ_NULLABLE(src->name, dst->name)) {                    \
 
1028
            virSmbiosReportError(VIR_ERR_CONFIG_UNSUPPORTED,            \
 
1029
                                 _("Target sysinfo %s %s does not match source %s"), \
 
1030
                                 desc, NULLSTR(src->name), NULLSTR(dst->name)); \
 
1031
        }                                                               \
 
1032
    } while (0)
 
1033
 
 
1034
    CHECK_FIELD(bios_vendor, "BIOS vendor");
 
1035
    CHECK_FIELD(bios_version, "BIOS version");
 
1036
    CHECK_FIELD(bios_date, "BIOS date");
 
1037
    CHECK_FIELD(bios_release, "BIOS release");
 
1038
 
 
1039
    CHECK_FIELD(system_manufacturer, "system vendor");
 
1040
    CHECK_FIELD(system_product, "system product");
 
1041
    CHECK_FIELD(system_version, "system version");
 
1042
    CHECK_FIELD(system_serial, "system serial");
 
1043
    CHECK_FIELD(system_uuid, "system uuid");
 
1044
    CHECK_FIELD(system_sku, "system sku");
 
1045
    CHECK_FIELD(system_family, "system family");
 
1046
 
 
1047
#undef CHECK_FIELD
 
1048
 
 
1049
    identical = true;
 
1050
 
 
1051
cleanup:
 
1052
    return identical;
 
1053
}