vbox_driver.c 6.7 KB
Newer Older
1 2 3 4 5
/** @file vbox_driver.c
 * Core driver methods for managing VirtualBox VM's
 */

/*
6
 * Copyright (C) 2010-2011 Red Hat, Inc.
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
 * Copyright (C) 2008-2009 Sun Microsystems, Inc.
 *
 * This file is part of a free software library; you can redistribute
 * it and/or modify it under the terms of the GNU Lesser General
 * Public License version 2.1 as published by the Free Software
 * Foundation and shipped in the "COPYING" file with this library.
 * The library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY of any kind.
 *
 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if
 * any license choice other than GPL or LGPL is available it will
 * apply instead, Sun elects to use only the Lesser General Public
 * License version 2.1 (LGPLv2) at this time for any software where
 * a choice of LGPL license versions is made available with the
 * language indicating that LGPLv2 or any later version may be used,
 * or where a choice of which version of the LGPL is applied is
 * otherwise unspecified.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 USA or visit http://www.sun.com if you need
 * additional information or have any questions.
 */

#include <config.h>

J
Jim Meyering 已提交
32 33 34 35
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>

36 37 38 39 40
#include "internal.h"

#include "datatypes.h"
#include "logging.h"
#include "vbox_driver.h"
41
#include "vbox_glue.h"
42
#include "virterror_internal.h"
43
#include "util.h"
44 45 46 47 48

#define VIR_FROM_THIS VIR_FROM_VBOX


extern virDriver vbox22Driver;
49
extern virNetworkDriver vbox22NetworkDriver;
50
extern virStorageDriver vbox22StorageDriver;
51 52
extern virDriver vbox30Driver;
extern virNetworkDriver vbox30NetworkDriver;
53
extern virStorageDriver vbox30StorageDriver;
54 55 56
extern virDriver vbox31Driver;
extern virNetworkDriver vbox31NetworkDriver;
extern virStorageDriver vbox31StorageDriver;
57 58 59
extern virDriver vbox32Driver;
extern virNetworkDriver vbox32NetworkDriver;
extern virStorageDriver vbox32StorageDriver;
60 61 62
extern virDriver vbox40Driver;
extern virNetworkDriver vbox40NetworkDriver;
extern virStorageDriver vbox40StorageDriver;
63 64 65
extern virDriver vbox41Driver;
extern virNetworkDriver vbox41NetworkDriver;
extern virStorageDriver vbox41StorageDriver;
66

67 68 69 70
static virDriver vboxDriverDummy;

#define VIR_FROM_THIS VIR_FROM_VBOX

71
int vboxRegister(void) {
72
    virDriverPtr        driver;
73
    virNetworkDriverPtr networkDriver;
74
    virStorageDriverPtr storageDriver;
75
    uint32_t            uVersion;
76

77 78 79 80 81
    /*
     * If the glue layer does not initialize, we register a driver
     * with a dummy open method, so we can report nicer errors
     * if the user requests a vbox:// URI which we know will
     * never work
82
     */
83
    driver        = &vboxDriverDummy;
84
    networkDriver = &vbox22NetworkDriver;
85
    storageDriver = &vbox22StorageDriver;
86

87
    /* Init the glue and get the API version. */
88
    if (VBoxCGlueInit(&uVersion) == 0) {
89
        VIR_DEBUG("VBoxCGlueInit found API version: %d.%d.%d (%u)",
90 91 92 93 94 95 96 97
              uVersion / 1000000,
              uVersion % 1000000 / 1000,
              uVersion % 1000,
              uVersion);

        /* Select driver implementation based on version.
         * Note that the VirtualBox development usually happens at build
         * number 51, thus the version ranges in the if statements below.
98
         */
99
        if (uVersion >= 2001052 && uVersion < 2002051) {
100
            VIR_DEBUG("VirtualBox API version: 2.2");
101
            driver        = &vbox22Driver;
102
            networkDriver = &vbox22NetworkDriver;
103
            storageDriver = &vbox22StorageDriver;
104
        } else if (uVersion >= 2002051 && uVersion < 3000051) {
105
            VIR_DEBUG("VirtualBox API version: 3.0");
106 107
            driver        = &vbox30Driver;
            networkDriver = &vbox30NetworkDriver;
108
            storageDriver = &vbox30StorageDriver;
109
        } else if (uVersion >= 3000051 && uVersion < 3001051) {
110
            VIR_DEBUG("VirtualBox API version: 3.1");
111 112 113
            driver        = &vbox31Driver;
            networkDriver = &vbox31NetworkDriver;
            storageDriver = &vbox31StorageDriver;
114
        } else if (uVersion >= 3001051 && uVersion < 3002051) {
115
            VIR_DEBUG("VirtualBox API version: 3.2");
116 117 118
            driver        = &vbox32Driver;
            networkDriver = &vbox32NetworkDriver;
            storageDriver = &vbox32StorageDriver;
119
        } else if (uVersion >= 3002051 && uVersion < 4000051) {
120
            VIR_DEBUG("VirtualBox API version: 4.0");
121 122 123
            driver        = &vbox40Driver;
            networkDriver = &vbox40NetworkDriver;
            storageDriver = &vbox40StorageDriver;
124 125 126 127 128
        } else if (uVersion >= 4000051 && uVersion < 4001051) {
            VIR_DEBUG("VirtualBox API version: 4.1");
            driver        = &vbox41Driver;
            networkDriver = &vbox41NetworkDriver;
            storageDriver = &vbox41StorageDriver;
129
        } else {
130
            VIR_DEBUG("Unsupported VirtualBox API version: %u", uVersion);
131
        }
132
    } else {
133
        VIR_DEBUG("VBoxCGlueInit failed, using dummy driver");
134 135 136 137
    }

    if (virRegisterDriver(driver) < 0)
        return -1;
138 139
    if (virRegisterNetworkDriver(networkDriver) < 0)
        return -1;
140 141
    if (virRegisterStorageDriver(storageDriver) < 0)
        return -1;
142 143 144

    return 0;
}
145 146 147

static virDrvOpenStatus vboxOpenDummy(virConnectPtr conn,
                                      virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
148 149
                                      unsigned int flags)
{
150 151
    uid_t uid = getuid();

E
Eric Blake 已提交
152 153
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

154 155 156 157 158 159 160
    if (conn->uri == NULL ||
        conn->uri->scheme == NULL ||
        STRNEQ (conn->uri->scheme, "vbox") ||
        conn->uri->server != NULL)
        return VIR_DRV_OPEN_DECLINED;

    if (conn->uri->path == NULL || STREQ(conn->uri->path, "")) {
161 162
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("no VirtualBox driver path specified (try vbox:///session)"));
163 164 165 166 167
        return VIR_DRV_OPEN_ERROR;
    }

    if (uid != 0) {
        if (STRNEQ (conn->uri->path, "/session")) {
168 169
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
170 171 172 173 174
            return VIR_DRV_OPEN_ERROR;
        }
    } else { /* root */
        if (STRNEQ (conn->uri->path, "/system") &&
            STRNEQ (conn->uri->path, "/session")) {
175 176
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unknown driver path '%s' specified (try vbox:///system)"), conn->uri->path);
177 178 179 180
            return VIR_DRV_OPEN_ERROR;
        }
    }

181 182
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                   _("unable to initialize VirtualBox driver API"));
183 184 185 186 187 188 189 190
    return VIR_DRV_OPEN_ERROR;
}

static virDriver vboxDriverDummy = {
    VIR_DRV_VBOX,
    "VBOX",
    .open = vboxOpenDummy,
};