~ressu/+junk/xen-debian

« back to all changes in this revision

Viewing changes to tools/libxl/libxl_utils.c

  • Committer: sami at haahtinen
  • Author(s): Bastian Blank
  • Date: 2011-03-17 14:12:45 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: sami@haahtinen.name-20110317141245-owgqox0l0p3g5857
Tags: 4.1.0~rc6-1
* New upstream release candidate.
* Build documentation using pdflatex.
* Use python 2.6. (closes: #596545)
* Fix lintian override.
* Install new tools: xl, xenpaging.
* Enable blktap2.
  - Use own md5 implementation.
  - Fix includes.
  - Fix linking of blktap2 binaries.
  - Remove optimization setting.
* Temporarily disable hvmloader, wants to download ipxe.
* Remove xenstored pid check from xl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include "libxl_utils.h"
32
32
#include "libxl_internal.h"
33
33
 
 
34
struct schedid_name {
 
35
    char *name;
 
36
    int id;
 
37
};
 
38
 
 
39
static struct schedid_name schedid_name[] = {
 
40
    { "credit", XEN_SCHEDULER_CREDIT },
 
41
    { "sedf", XEN_SCHEDULER_SEDF },
 
42
    { "credit2", XEN_SCHEDULER_CREDIT2 },
 
43
    { NULL, -1 }
 
44
};
 
45
 
 
46
const char *libxl_basename(const char *name)
 
47
{
 
48
    const char *filename;
 
49
    if (name == NULL)
 
50
        return strdup(".");
 
51
    if (name[0] == '\0')
 
52
        return strdup(".");
 
53
 
 
54
    filename = strrchr(name, '/');
 
55
    if (filename)
 
56
        return strdup(filename+1);
 
57
    return strdup(name);
 
58
}
34
59
 
35
60
unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus)
36
61
{
43
68
    return 4 * (256 * smp_cpus + 2 * (maxmem_kb / 1024));
44
69
}
45
70
 
46
 
char *libxl_domid_to_name(struct libxl_ctx *ctx, uint32_t domid)
 
71
char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid)
47
72
{
48
73
    unsigned int len;
49
74
    char path[strlen("/local/domain") + 12];
51
76
 
52
77
    snprintf(path, sizeof(path), "/local/domain/%d/name", domid);
53
78
    s = xs_read(ctx->xsh, XBT_NULL, path, &len);
54
 
    libxl_ptr_add(ctx, s);
55
 
    return s;
56
 
}
57
 
 
58
 
int libxl_name_to_domid(struct libxl_ctx *ctx, const char *name,
 
79
    return s;
 
80
}
 
81
 
 
82
char *libxl__domid_to_name(libxl__gc *gc, uint32_t domid)
 
83
{
 
84
    char *s = libxl_domid_to_name(libxl__gc_owner(gc), domid);
 
85
    if ( s )
 
86
        libxl__ptr_add(gc, s);
 
87
    return s;
 
88
}
 
89
 
 
90
int libxl_name_to_domid(libxl_ctx *ctx, const char *name,
59
91
                        uint32_t *domid)
60
92
{
61
93
    int i, nb_domains;
62
94
    char *domname;
63
 
    struct libxl_dominfo *dominfo;
 
95
    libxl_dominfo *dominfo;
 
96
    int ret = ERROR_INVAL;
64
97
 
65
98
    dominfo = libxl_list_domain(ctx, &nb_domains);
66
99
    if (!dominfo)
72
105
            continue;
73
106
        if (strcmp(domname, name) == 0) {
74
107
            *domid = dominfo[i].domid;
75
 
            return 0;
 
108
            ret = 0;
 
109
            free(domname);
 
110
            break;
76
111
        }
 
112
        free(domname);
77
113
    }
78
 
    return -1;
 
114
    free(dominfo);
 
115
    return ret;
79
116
}
80
117
 
81
 
char *libxl_poolid_to_name(struct libxl_ctx *ctx, uint32_t poolid)
 
118
char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid)
82
119
{
83
120
    unsigned int len;
84
121
    char path[strlen("/local/pool") + 12];
85
122
    char *s;
86
123
 
87
 
    if (poolid == 0)
88
 
        return "Pool-0";
89
124
    snprintf(path, sizeof(path), "/local/pool/%d/name", poolid);
90
125
    s = xs_read(ctx->xsh, XBT_NULL, path, &len);
91
 
    libxl_ptr_add(ctx, s);
92
 
    return s;
93
 
}
94
 
 
95
 
int libxl_get_stubdom_id(struct libxl_ctx *ctx, int guest_domid)
96
 
{
97
 
    char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid)));
 
126
    if (!s && (poolid == 0))
 
127
        return strdup("Pool-0");
 
128
    return s;
 
129
}
 
130
 
 
131
char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid)
 
132
{
 
133
    char *s = libxl_cpupoolid_to_name(libxl__gc_owner(gc), poolid);
 
134
    if ( s )
 
135
        libxl__ptr_add(gc, s);
 
136
    return s;
 
137
}
 
138
 
 
139
int libxl_name_to_cpupoolid(libxl_ctx *ctx, const char *name,
 
140
                        uint32_t *poolid)
 
141
{
 
142
    int i, nb_pools;
 
143
    char *poolname;
 
144
    libxl_cpupoolinfo *poolinfo;
 
145
    int ret = ERROR_INVAL;
 
146
 
 
147
    poolinfo = libxl_list_cpupool(ctx, &nb_pools);
 
148
    if (!poolinfo)
 
149
        return ERROR_NOMEM;
 
150
 
 
151
    for (i = 0; i < nb_pools; i++) {
 
152
        if (ret && ((poolname = libxl_cpupoolid_to_name(ctx,
 
153
            poolinfo[i].poolid)) != NULL)) {
 
154
            if (strcmp(poolname, name) == 0) {
 
155
                *poolid = poolinfo[i].poolid;
 
156
                ret = 0;
 
157
            }
 
158
            free(poolname);
 
159
        }
 
160
        libxl_cpupoolinfo_destroy(poolinfo + i);
 
161
    }
 
162
    free(poolinfo);
 
163
    return ret;
 
164
}
 
165
 
 
166
int libxl_name_to_schedid(libxl_ctx *ctx, const char *name)
 
167
{
 
168
    int i;
 
169
 
 
170
    for (i = 0; schedid_name[i].name != NULL; i++)
 
171
        if (strcmp(name, schedid_name[i].name) == 0)
 
172
            return schedid_name[i].id;
 
173
 
 
174
    return ERROR_INVAL;
 
175
}
 
176
 
 
177
char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid)
 
178
{
 
179
    int i;
 
180
 
 
181
    for (i = 0; schedid_name[i].name != NULL; i++)
 
182
        if (schedid_name[i].id == schedid)
 
183
            return schedid_name[i].name;
 
184
 
 
185
    return "unknown";
 
186
}
 
187
 
 
188
int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid)
 
189
{
 
190
    libxl__gc gc = LIBXL_INIT_GC(ctx);
 
191
    char * stubdom_id_s;
 
192
    int ret;
 
193
 
 
194
    stubdom_id_s = libxl__xs_read(&gc, XBT_NULL,
 
195
                                 libxl__sprintf(&gc, "%s/image/device-model-domid",
 
196
                                               libxl__xs_get_dompath(&gc, guest_domid)));
98
197
    if (stubdom_id_s)
99
 
        return atoi(stubdom_id_s);
 
198
        ret = atoi(stubdom_id_s);
100
199
    else
101
 
        return 0;
 
200
        ret = 0;
 
201
    libxl__free_all(&gc);
 
202
    return ret;
102
203
}
103
204
 
104
 
int libxl_is_stubdom(struct libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid)
 
205
int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid)
105
206
{
 
207
    libxl__gc gc = LIBXL_INIT_GC(ctx);
106
208
    char *target, *endptr;
107
209
    uint32_t value;
 
210
    int ret = 0;
108
211
 
109
 
    target = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid)));
 
212
    target = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)));
110
213
    if (!target)
111
 
        return 0;
 
214
        goto out;
112
215
    value = strtol(target, &endptr, 10);
113
216
    if (*endptr != '\0')
114
 
        return 0;
 
217
        goto out;
115
218
    if (target_domid)
116
219
        *target_domid = value;
117
 
    return 1;
 
220
    ret = 1;
 
221
out:
 
222
    libxl__free_all(&gc);
 
223
    return ret;
118
224
}
119
225
 
120
 
static int logrename(struct libxl_ctx *ctx, const char *old, const char *new) {
 
226
static int logrename(libxl_ctx *ctx, const char *old, const char *new) {
121
227
    int r;
122
228
 
123
229
    r = rename(old, new);
124
230
    if (r) {
125
231
        if (errno == ENOENT) return 0; /* ok */
126
232
 
127
 
        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to rotate logfile - could not"
 
233
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to rotate logfile - could not"
128
234
                     " rename %s to %s", old, new);
129
235
        return ERROR_FAIL;
130
236
    }
131
237
    return 0;
132
238
}
133
239
 
134
 
int libxl_create_logfile(struct libxl_ctx *ctx, char *name, char **full_name)
 
240
int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name)
135
241
{
 
242
    libxl__gc gc = LIBXL_INIT_GC(ctx);
136
243
    struct stat stat_buf;
137
244
    char *logfile, *logfile_new;
138
245
    int i, rc;
139
246
 
140
 
    logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
 
247
    logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log", name);
141
248
    if (stat(logfile, &stat_buf) == 0) {
142
249
        /* file exists, rotate */
143
 
        logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.10", name);
 
250
        logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log.10", name);
144
251
        unlink(logfile);
145
252
        for (i = 9; i > 0; i--) {
146
 
            logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i);
147
 
            logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i + 1);
 
253
            logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log.%d", name, i);
 
254
            logfile_new = libxl__sprintf(&gc, "/var/log/xen/%s.log.%d", name, i + 1);
148
255
            rc = logrename(ctx, logfile, logfile_new);
149
 
            if (rc) return rc;
 
256
            if (rc)
 
257
                goto out;
150
258
        }
151
 
        logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
152
 
        logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.1", name);
 
259
        logfile = libxl__sprintf(&gc, "/var/log/xen/%s.log", name);
 
260
        logfile_new = libxl__sprintf(&gc, "/var/log/xen/%s.log.1", name);
153
261
 
154
262
        rc = logrename(ctx, logfile, logfile_new);
155
 
        if (rc) return rc;
 
263
        if (rc)
 
264
            goto out;
156
265
    } else {
157
266
        if (errno != ENOENT)
158
 
            XL_LOG_ERRNO(ctx, XL_LOG_WARNING, "problem checking existence of"
 
267
            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_WARNING, "problem checking existence of"
159
268
                         " logfile %s, which might have needed to be rotated",
160
269
                         name);
161
270
    }
162
271
    *full_name = strdup(logfile);
163
 
    return 0;
 
272
    rc = 0;
 
273
out:
 
274
    libxl__free_all(&gc);
 
275
    return rc;
164
276
}
165
277
 
166
 
int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, libxl_disk_phystype *phystype)
 
278
int libxl_string_to_backend(libxl_ctx *ctx, char *s, libxl_disk_backend *backend)
167
279
{
168
280
    char *p;
169
281
    int rc = 0;
170
282
 
171
283
    if (!strcmp(s, "phy")) {
172
 
        *phystype = PHYSTYPE_PHY;
 
284
        *backend = DISK_BACKEND_PHY;
173
285
    } else if (!strcmp(s, "file")) {
174
 
        *phystype = PHYSTYPE_FILE;
 
286
        *backend = DISK_BACKEND_TAP;
175
287
    } else if (!strcmp(s, "tap")) {
176
288
        p = strchr(s, ':');
177
289
        if (!p) {
178
 
            rc = -1;
 
290
            rc = ERROR_INVAL;
179
291
            goto out;
180
292
        }
181
293
        p++;
182
 
        if (!strcmp(p, "aio")) {
183
 
            *phystype = PHYSTYPE_AIO;
184
 
        } else if (!strcmp(p, "vhd")) {
185
 
            *phystype = PHYSTYPE_VHD;
 
294
        if (!strcmp(p, "vhd")) {
 
295
            *backend = DISK_BACKEND_TAP;
186
296
        } else if (!strcmp(p, "qcow")) {
187
 
            *phystype = PHYSTYPE_QCOW;
 
297
            *backend = DISK_BACKEND_QDISK;
188
298
        } else if (!strcmp(p, "qcow2")) {
189
 
            *phystype = PHYSTYPE_QCOW2;
 
299
            *backend = DISK_BACKEND_QDISK;
190
300
        }
191
301
    }
192
302
out:
193
303
    return rc;
194
304
}
195
305
 
196
 
int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename,
 
306
int libxl_read_file_contents(libxl_ctx *ctx, const char *filename,
197
307
                             void **data_r, int *datalen_r) {
198
308
    FILE *f = 0;
199
309
    uint8_t *data = 0;
201
311
    int e;
202
312
    struct stat stab;
203
313
    ssize_t rs;
204
 
 
 
314
    
205
315
    f = fopen(filename, "r");
206
316
    if (!f) {
207
317
        if (errno == ENOENT) return ENOENT;
208
 
        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to open %s", filename);
 
318
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to open %s", filename);
209
319
        goto xe;
210
320
    }
211
321
 
212
322
    if (fstat(fileno(f), &stab)) {
213
 
        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to fstat %s", filename);
 
323
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to fstat %s", filename);
214
324
        goto xe;
215
325
    }
216
326
 
217
327
    if (!S_ISREG(stab.st_mode)) {
218
 
        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "%s is not a plain file", filename);
 
328
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "%s is not a plain file", filename);
219
329
        errno = ENOTTY;
220
330
        goto xe;
221
331
    }
222
332
 
223
333
    if (stab.st_size > INT_MAX) {
224
 
        XL_LOG(ctx, XL_LOG_ERROR, "file %s is far too large", filename);
 
334
        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "file %s is far too large", filename);
225
335
        errno = EFBIG;
226
336
        goto xe;
227
337
    }
235
345
        rs = fread(data, 1, datalen, f);
236
346
        if (rs != datalen) {
237
347
            if (ferror(f))
238
 
                XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to read %s", filename);
 
348
                LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to read %s", filename);
239
349
            else if (feof(f))
240
 
                XL_LOG(ctx, XL_LOG_ERROR, "%s changed size while we"
 
350
                LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "%s changed size while we"
241
351
                       " were reading it", filename);
242
352
            else
243
353
                abort();
247
357
 
248
358
    if (fclose(f)) {
249
359
        f = 0;
250
 
        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to close %s", filename);
 
360
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to close %s", filename);
251
361
        goto xe;
252
362
    }
253
363
 
266
376
 
267
377
#define READ_WRITE_EXACTLY(rw, zero_is_eof, constdata)                    \
268
378
                                                                          \
269
 
  int libxl_##rw##_exactly(struct libxl_ctx *ctx, int fd,                 \
 
379
  int libxl_##rw##_exactly(libxl_ctx *ctx, int fd,                 \
270
380
                           constdata void *data, ssize_t sz,              \
271
381
                           const char *filename, const char *what) {      \
272
382
      ssize_t got;                                                        \
276
386
          if (got == -1) {                                                \
277
387
              if (errno == EINTR) continue;                               \
278
388
              if (!ctx) return errno;                                     \
279
 
              XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to " #rw " %s%s%s", \
 
389
              LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to " #rw " %s%s%s", \
280
390
                           what?what:"", what?" from ":"", filename);     \
281
391
              return errno;                                               \
282
392
          }                                                               \
283
393
          if (got == 0) {                                                 \
284
394
              if (!ctx) return EPROTO;                                    \
285
 
              XL_LOG(ctx, XL_LOG_ERROR,                                   \
 
395
              LIBXL__LOG(ctx, LIBXL__LOG_ERROR,                                   \
286
396
                     zero_is_eof                                          \
287
397
                     ? "file/stream truncated reading %s%s%s"             \
288
398
                     : "file/stream write returned 0! writing %s%s%s",    \
299
409
READ_WRITE_EXACTLY(write, 0, const)
300
410
 
301
411
 
302
 
int libxl_ctx_postfork(struct libxl_ctx *ctx) {
 
412
int libxl_ctx_postfork(libxl_ctx *ctx) {
303
413
    if (ctx->xsh) xs_daemon_destroy_postfork(ctx->xsh);
304
414
    ctx->xsh = xs_daemon_open();
305
415
    if (!ctx->xsh) return ERROR_FAIL;
306
416
    return 0;
307
417
}
308
418
 
309
 
pid_t libxl_fork(struct libxl_ctx *ctx)
 
419
pid_t libxl_fork(libxl_ctx *ctx)
310
420
{
311
421
    pid_t pid;
312
422
 
313
423
    pid = fork();
314
424
    if (pid == -1) {
315
 
        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "fork failed");
 
425
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "fork failed");
316
426
        return -1;
317
427
    }
318
428
 
327
437
    return pid;
328
438
}
329
439
 
330
 
int libxl_pipe(struct libxl_ctx *ctx, int pipes[2])
 
440
int libxl_pipe(libxl_ctx *ctx, int pipes[2])
331
441
{
332
442
    if (pipe(pipes) < 0) {
333
 
        XL_LOG(ctx, XL_LOG_ERROR, "Failed to create a pipe");
 
443
        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Failed to create a pipe");
334
444
        return -1;
335
445
    }
336
446
    return 0;
337
447
}
338
448
 
339
 
int libxl_mac_to_device_nic(struct libxl_ctx *ctx, uint32_t domid,
 
449
int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid,
340
450
                            const char *mac, libxl_device_nic *nic)
341
451
{
342
452
    libxl_nicinfo *nics;
343
453
    unsigned int nb, i;
 
454
    int found;
344
455
    uint8_t mac_n[6];
345
456
    uint8_t *a, *b;
346
457
    const char *tok;
347
458
    char *endptr;
348
459
 
349
460
    nics = libxl_list_nics(ctx, domid, &nb);
350
 
    if (!nics) {
 
461
    if (!nics)
351
462
        return ERROR_FAIL;
352
 
    }
353
463
 
354
464
    for (i = 0, tok = mac; *tok && (i < 6); ++i, tok += 3) {
355
465
        mac_n[i] = strtol(tok, &endptr, 16);
356
 
        if (endptr != (tok + 2)) {
 
466
        if (endptr != (tok + 2))
357
467
            return ERROR_INVAL;
358
 
        }
359
468
    }
360
469
    memset(nic, 0, sizeof (libxl_device_nic));
361
 
    for (; nb; --nb, ++nics) {
362
 
        for (i = 0, a = nics->mac, b = mac_n;
 
470
    found = 0;
 
471
    for (i = 0; i < nb; ++i) {
 
472
        for (i = 0, a = nics[i].mac, b = mac_n;
363
473
             (b < mac_n + 6) && (*a == *b); ++a, ++b)
364
474
            ;
365
475
        if ((b >= mac_n + 6) && (*a == *b)) {
366
 
            nic->backend_domid = nics->backend_id;
367
 
            nic->domid = nics->frontend_id;
368
 
            nic->devid = nics->devid;
369
 
            memcpy(nic->mac, nics->mac, sizeof (nic->mac));
370
 
            nic->script = nics->script;
371
 
            libxl_free(ctx, nics);
372
 
            return 0;
 
476
            nic->backend_domid = nics[i].backend_id;
 
477
            nic->domid = nics[i].frontend_id;
 
478
            nic->devid = nics[i].devid;
 
479
            memcpy(nic->mac, nics[i].mac, sizeof (nic->mac));
 
480
            nic->script = strdup(nics[i].script);
 
481
            found = 1;
 
482
            break;
373
483
        }
374
484
    }
375
485
 
376
 
    libxl_free(ctx, nics);
377
 
    return 0;
 
486
    for (i=0; i<nb; i++)
 
487
        libxl_nicinfo_destroy(&nics[i]);
 
488
    free(nics);
 
489
    return found;
378
490
}
379
491
 
380
 
int libxl_devid_to_device_nic(struct libxl_ctx *ctx, uint32_t domid,
 
492
int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid,
381
493
                              const char *devid, libxl_device_nic *nic)
382
494
{
 
495
    libxl__gc gc = LIBXL_INIT_GC(ctx);
383
496
    char *tok, *val;
384
497
    char *dompath, *nic_path_fe, *nic_path_be;
385
498
    unsigned int i;
 
499
    int rc = ERROR_FAIL;
386
500
 
387
501
    memset(nic, 0, sizeof (libxl_device_nic));
388
 
    dompath = libxl_xs_get_dompath(ctx, domid);
 
502
    dompath = libxl__xs_get_dompath(&gc, domid);
389
503
    if (!dompath) {
390
 
        return ERROR_FAIL;
391
 
    }
392
 
    nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, devid);
393
 
    nic_path_be = libxl_xs_read(ctx, XBT_NULL,
394
 
                                libxl_sprintf(ctx, "%s/backend", nic_path_fe));
395
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", nic_path_fe));
 
504
        goto out;
 
505
    }
 
506
    nic_path_fe = libxl__sprintf(&gc, "%s/device/vif/%s", dompath, devid);
 
507
    nic_path_be = libxl__xs_read(&gc, XBT_NULL,
 
508
                                libxl__sprintf(&gc, "%s/backend", nic_path_fe));
 
509
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend-id", nic_path_fe));
 
510
    if ( NULL == val ) {
 
511
        goto out;
 
512
    }
396
513
    nic->backend_domid = strtoul(val, NULL, 10);
397
514
    nic->devid = strtoul(devid, NULL, 10);
398
 
    libxl_free(ctx, val);
399
515
 
400
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", nic_path_fe));
 
516
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mac", nic_path_fe));
401
517
    for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
402
518
         ++i, tok = strtok(NULL, ":")) {
403
519
        nic->mac[i] = strtoul(tok, NULL, 16);
404
520
    }
405
 
    libxl_free(ctx, val);
406
 
    nic->script = libxl_xs_read(ctx, XBT_NULL,
407
 
                                libxl_sprintf(ctx, "%s/script", nic_path_be));
408
 
    libxl_free(ctx, nic_path_fe);
409
 
    libxl_free(ctx, nic_path_be);
410
 
    return 0;
 
521
    nic->script = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "%s/script", nic_path_be), NULL);
 
522
    rc = 0;
 
523
out:
 
524
    libxl__free_all(&gc);
 
525
    return rc;
411
526
}
412
527
 
413
 
int libxl_devid_to_device_disk(struct libxl_ctx *ctx, uint32_t domid,
 
528
int libxl_devid_to_device_disk(libxl_ctx *ctx, uint32_t domid,
414
529
                               const char *devid, libxl_device_disk *disk)
415
530
{
 
531
    libxl__gc gc = LIBXL_INIT_GC(ctx);
416
532
    char *endptr, *val;
417
533
    char *dompath, *diskpath, *be_path;
418
534
    unsigned int devid_n;
 
535
    int rc = ERROR_INVAL;
419
536
 
420
537
    devid_n = strtoul(devid, &endptr, 10);
421
538
    if (devid == endptr) {
422
 
        return ERROR_INVAL;
 
539
        goto out;
423
540
    }
424
 
    dompath = libxl_xs_get_dompath(ctx, domid);
425
 
    diskpath = libxl_sprintf(ctx, "%s/device/vbd/%s", dompath, devid);
 
541
    rc = ERROR_FAIL;
 
542
    dompath = libxl__xs_get_dompath(&gc, domid);
 
543
    diskpath = libxl__sprintf(&gc, "%s/device/vbd/%s", dompath, devid);
426
544
    if (!diskpath) {
427
 
        return ERROR_FAIL;
 
545
        goto out;
428
546
    }
429
547
 
430
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", diskpath));
 
548
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend-id", diskpath));
 
549
    if (!val)
 
550
        goto out;
431
551
    disk->backend_domid = strtoul(val, NULL, 10);
432
552
    disk->domid = domid;
433
 
    be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", diskpath));
434
 
    disk->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/params", be_path));
435
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/type", be_path));
436
 
    libxl_string_to_phystype(ctx, val, &(disk->phystype));
437
 
    disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", be_path));
438
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/removable", be_path));
 
553
    be_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend", diskpath));
 
554
    disk->pdev_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/params", be_path));
 
555
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/type", be_path));
 
556
    libxl_string_to_backend(ctx, val, &(disk->backend));
 
557
    disk->vdev = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/dev", be_path));
 
558
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/removable", be_path));
439
559
    disk->unpluggable = !strcmp(val, "1");
440
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mode", be_path));
 
560
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mode", be_path));
441
561
    disk->readwrite = !!strcmp(val, "w");
442
 
    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", diskpath));
 
562
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/device-type", diskpath));
443
563
    disk->is_cdrom = !strcmp(val, "cdrom");
444
 
 
445
 
    return 0;
 
564
    rc = 0;
 
565
 
 
566
out:
 
567
    libxl__free_all(&gc);
 
568
    return rc;
 
569
}
 
570
 
 
571
int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
 
572
                               const char *devid, libxl_device_net2 *net2)
 
573
{
 
574
    libxl__gc gc = LIBXL_INIT_GC(ctx);
 
575
    char *tok, *endptr, *val;
 
576
    char *dompath, *net2path, *be_path;
 
577
    unsigned int devid_n, i;
 
578
    int rc = ERROR_INVAL;
 
579
 
 
580
    devid_n = strtoul(devid, &endptr, 10);
 
581
    if (devid == endptr) {
 
582
        goto out;
 
583
    }
 
584
    rc = ERROR_FAIL;
 
585
    dompath = libxl__xs_get_dompath(&gc, domid);
 
586
    net2path = libxl__sprintf(&gc, "%s/device/vif2/%s", dompath, devid);
 
587
    if (!net2path) {
 
588
        goto out;
 
589
    }
 
590
    memset(net2, 0, sizeof (libxl_device_net2));
 
591
    be_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend", net2path));
 
592
 
 
593
    net2->devid = devid_n;
 
594
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/mac", net2path));
 
595
    for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
 
596
         ++i, tok = strtok(NULL, ":")) {
 
597
        net2->front_mac[i] = strtoul(tok, NULL, 16);
 
598
    }
 
599
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/remote-mac", net2path));
 
600
    for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
 
601
         ++i, tok = strtok(NULL, ":")) {
 
602
        net2->back_mac[i] = strtoul(tok, NULL, 16);
 
603
    }
 
604
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend-id", net2path));
 
605
    net2->backend_domid = strtoul(val, NULL, 10);
 
606
 
 
607
    net2->domid = domid;
 
608
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/remote-trusted", be_path));
 
609
    net2->trusted = strtoul(val, NULL, 10);
 
610
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/local-trusted", be_path));
 
611
    net2->back_trusted = strtoul(val, NULL, 10);
 
612
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/filter-mac", be_path));
 
613
    net2->filter_mac = strtoul(val, NULL, 10);
 
614
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/filter-mac", net2path));
 
615
    net2->front_filter_mac = strtoul(val, NULL, 10);
 
616
    val = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/max-bypasses", be_path));
 
617
    net2->max_bypasses = strtoul(val, NULL, 10);
 
618
    rc = 0;
 
619
 
 
620
out:
 
621
    libxl__free_all(&gc);
 
622
    return rc;
 
623
}
 
624
 
 
625
int libxl_strtomac(const char *mac_s, uint8_t *mac)
 
626
{
 
627
    const char *end = mac_s + 17;
 
628
    char val, *endptr;
 
629
 
 
630
    for (; mac_s < end; mac_s += 3, ++mac) {
 
631
        val = strtoul(mac_s, &endptr, 16);
 
632
        if (endptr != (mac_s + 2)) {
 
633
            return ERROR_INVAL;
 
634
        }
 
635
        *mac = val;
 
636
    }
 
637
    return 0;
 
638
}
 
639
 
 
640
#define QEMU_VERSION_STR  "QEMU emulator version "
 
641
 
 
642
 
 
643
int libxl_check_device_model_version(libxl_ctx *ctx, char *path)
 
644
{
 
645
    libxl__gc gc = LIBXL_INIT_GC(ctx);
 
646
    pid_t pid = -1;
 
647
    int pipefd[2];
 
648
    char buf[100];
 
649
    ssize_t i, count = 0;
 
650
    int status;
 
651
    char *abs_path = NULL;
 
652
    int rc = -1;
 
653
 
 
654
    abs_path = libxl__abs_path(&gc, path, libxl_private_bindir_path());
 
655
 
 
656
    if (pipe(pipefd))
 
657
        goto out;
 
658
 
 
659
    pid = fork();
 
660
    if (pid == -1) {
 
661
        goto out;
 
662
    }
 
663
 
 
664
    if (!pid) {
 
665
        close(pipefd[0]);
 
666
        if (dup2(pipefd[1], STDOUT_FILENO) == -1)
 
667
            exit(1);
 
668
        execlp(abs_path, abs_path, "-h", NULL);
 
669
 
 
670
        close(pipefd[1]);
 
671
        exit(127);
 
672
    }
 
673
 
 
674
    close(pipefd[1]);
 
675
 
 
676
    /* attempt to get the first line of `qemu -h` */
 
677
    while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) {
 
678
        if (i + count > 90)
 
679
            break;
 
680
        for (int j = 0; j <  i; j++) {
 
681
            if (buf[j + count] == '\n')
 
682
                break;
 
683
        }
 
684
        count += i;
 
685
    }
 
686
    count += i;
 
687
    close(pipefd[0]);
 
688
    waitpid(pid, &status, 0);
 
689
    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 
690
        goto out;
 
691
    }
 
692
 
 
693
    /* Check if we have the forked qemu-xen. */
 
694
    /* QEMU-DM emulator version 0.10.2, ... */
 
695
    if (strncmp("QEMU-DM ", buf, 7) == 0) {
 
696
        rc = 0;
 
697
        goto out;
 
698
    }
 
699
 
 
700
    /* Check if the version is above 12.0 */
 
701
    /* The first line is : QEMU emulator version 0.12.50, ... */
 
702
    if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) {
 
703
        int major, minor;
 
704
        char *endptr = NULL;
 
705
        char *v = buf + strlen(QEMU_VERSION_STR);
 
706
 
 
707
        major = strtol(v, &endptr, 10);
 
708
        if (major == 0 && endptr && *endptr == '.') {
 
709
            v = endptr + 1;
 
710
            minor = strtol(v, &endptr, 10);
 
711
            if (minor >= 12) {
 
712
                rc = 1;
 
713
                goto out;
 
714
            }
 
715
        }
 
716
    }
 
717
    rc = 0;
 
718
out:
 
719
    libxl__free_all(&gc);
 
720
    return rc;
 
721
}
 
722
 
 
723
int libxl_cpumap_alloc(libxl_ctx *ctx, libxl_cpumap *cpumap)
 
724
{
 
725
    int max_cpus;
 
726
    int sz;
 
727
 
 
728
    max_cpus = libxl_get_max_cpus(ctx);
 
729
    if (max_cpus == 0)
 
730
        return ERROR_FAIL;
 
731
 
 
732
    sz = (max_cpus + 7) / 8;
 
733
    cpumap->map = calloc(sz, sizeof(*cpumap->map));
 
734
    if (!cpumap->map)
 
735
        return ERROR_NOMEM;
 
736
    cpumap->size = sz;
 
737
    return 0;
 
738
}
 
739
 
 
740
void libxl_cpumap_destroy(libxl_cpumap *map)
 
741
{
 
742
    free(map->map);
 
743
}
 
744
 
 
745
int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu)
 
746
{
 
747
    if (cpu >= cpumap->size * 8)
 
748
        return 0;
 
749
    return (cpumap->map[cpu / 8] & (1 << (cpu & 7))) ? 1 : 0;
 
750
}
 
751
 
 
752
void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu)
 
753
{
 
754
    if (cpu >= cpumap->size * 8)
 
755
        return;
 
756
    cpumap->map[cpu / 8] |= 1 << (cpu & 7);
 
757
}
 
758
 
 
759
void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu)
 
760
{
 
761
    if (cpu >= cpumap->size * 8)
 
762
        return;
 
763
    cpumap->map[cpu / 8] &= ~(1 << (cpu & 7));
 
764
}
 
765
 
 
766
int libxl_cpuarray_alloc(libxl_ctx *ctx, libxl_cpuarray *cpuarray)
 
767
{
 
768
    int max_cpus;
 
769
    int i;
 
770
 
 
771
    max_cpus = libxl_get_max_cpus(ctx);
 
772
    if (max_cpus == 0)
 
773
        return ERROR_FAIL;
 
774
 
 
775
    cpuarray->array = calloc(max_cpus, sizeof(*cpuarray->array));
 
776
    if (!cpuarray->array)
 
777
        return ERROR_NOMEM;
 
778
    cpuarray->entries = max_cpus;
 
779
    for (i = 0; i < max_cpus; i++)
 
780
        cpuarray->array[i] = LIBXL_CPUARRAY_INVALID_ENTRY;
 
781
 
 
782
    return 0;
 
783
}
 
784
 
 
785
void libxl_cpuarray_destroy(libxl_cpuarray *array)
 
786
{
 
787
    free(array->array);
 
788
}
 
789
 
 
790
int libxl_get_max_cpus(libxl_ctx *ctx)
 
791
{
 
792
    return xc_get_max_cpus(ctx->xch);
446
793
}