driver.c 7.8 KB
Newer Older
O
overweight 已提交
1 2
/******************************************************************************
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3 4 5 6
 * iSulad licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
O
overweight 已提交
7 8 9
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
10
 * See the Mulan PSL v2 for more details.
O
overweight 已提交
11 12 13 14 15 16 17 18 19 20 21 22
 * Author: tanyifeng
 * Create: 2017-11-22
 * Description: provide image functions
 ******************************************************************************/
#include "driver.h"

#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <linux/limits.h>

#include "driver_overlay2.h"
W
WangFengTu 已提交
23
#include "driver_devmapper.h"
O
overweight 已提交
24
#include "utils.h"
L
LiuHao 已提交
25
#include "libisulad.h"
H
haozi007 已提交
26
#include "isula_libutils/log.h"
L
LiuHao 已提交
27
#include "isulad_config.h"
D
dogsheng 已提交
28
#include "image.h"
29
#include "util_archive.h"
O
overweight 已提交
30

L
LiFeng 已提交
31 32 33
static struct graphdriver *g_graphdriver = NULL;

/* overlay2 */
O
overweight 已提交
34 35 36
#define DRIVER_OVERLAY2_NAME "overlay2"
static const struct graphdriver_ops g_overlay2_ops = {
    .init = overlay2_init,
37
    .create_rw = overlay2_create_rw,
L
LiFeng 已提交
38
    .create_ro = overlay2_create_ro,
39 40 41 42 43
    .rm_layer = overlay2_rm_layer,
    .mount_layer = overlay2_mount_layer,
    .umount_layer = overlay2_umount_layer,
    .exists = overlay2_layer_exists,
    .apply_diff = overlay2_apply_diff,
L
LiFeng 已提交
44 45
    .get_layer_metadata = overlay2_get_layer_metadata,
    .get_driver_status = overlay2_get_driver_status,
L
LiFeng 已提交
46
    .clean_up = overlay2_clean_up,
O
overweight 已提交
47 48
};

W
WangFengTu 已提交
49 50 51 52 53 54 55
/* devicemapper */
#define DRIVER_DEVMAPPER_NAME "devicemapper"

static const struct graphdriver_ops g_devmapper_ops = {
    .init = devmapper_init,
};

O
overweight 已提交
56
static struct graphdriver g_drivers[] = {
W
WangFengTu 已提交
57 58
    {.name = DRIVER_OVERLAY2_NAME, .ops = &g_overlay2_ops},
    {.name = DRIVER_DEVMAPPER_NAME, .ops = &g_devmapper_ops}
O
overweight 已提交
59 60 61 62
};

static const size_t g_numdrivers = sizeof(g_drivers) / sizeof(struct graphdriver);

L
LiFeng 已提交
63
int graphdriver_init(struct storage_module_init_options *opts)
O
overweight 已提交
64
{
65
    int ret = 0;
O
overweight 已提交
66
    size_t i = 0;
67
    char driver_home[PATH_MAX] = { 0 };
O
overweight 已提交
68

L
LiFeng 已提交
69
    if (opts == NULL || opts->storage_root == NULL || opts->driver_name == NULL) {
70 71
        ret = -1;
        goto out;
72 73
    }

L
LiFeng 已提交
74
    int nret = snprintf(driver_home, PATH_MAX, "%s/%s", opts->storage_root, opts->driver_name);
75 76
    if (nret < 0 || (size_t)nret >= PATH_MAX) {
        ERROR("Sprintf graph driver path failed");
77 78
        ret = -1;
        goto out;
O
overweight 已提交
79 80 81
    }

    for (i = 0; i < g_numdrivers; i++) {
L
LiFeng 已提交
82 83
        if (strcmp(opts->driver_name, g_drivers[i].name) == 0) {
            if (g_drivers[i].ops->init(&g_drivers[i], driver_home, (const char **)opts->driver_opts, opts->driver_opts_len) != 0) {
84
                ret = -1;
L
LiFeng 已提交
85
                goto out;
86
            }
L
LiFeng 已提交
87 88 89 90
            g_graphdriver = &g_drivers[i];
            break;
        }
    }
91

92
    if (i == g_numdrivers) {
L
LiFeng 已提交
93
        ERROR("unsupported driver %s", opts->driver_name);
94 95 96
        ret = -1;
        goto out;
    }
97

98 99 100 101 102 103 104 105 106 107
    //just for test
    struct driver_create_opts test_create_opts = { 0 };
    struct driver_mount_opts test_mount_opts = { 0 };
    graphdriver_create_ro("1", "", &test_create_opts);
    graphdriver_create_ro("2", "1", &test_create_opts);
    graphdriver_create_ro("3", "2", &test_create_opts);
    graphdriver_create_ro("4", "3", &test_create_opts);
    graphdriver_create_rw("5", "4", &test_create_opts);
    ERROR("mount: %s", graphdriver_mount_layer("5", &test_mount_opts));
    //end test
108

109 110 111
out:
    return ret;
}
112

L
LiFeng 已提交
113
int graphdriver_create_rw(const char *id, const char *parent, struct driver_create_opts *create_opts)
L
LiFeng 已提交
114 115 116 117
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
118 119
    }

L
LiFeng 已提交
120 121 122 123 124 125
    if (id == NULL || parent == NULL || create_opts == NULL) {
        ERROR("Invalid input arguments for driver create");
        return -1;
    }

    return g_graphdriver->ops->create_rw(id, parent, g_graphdriver, create_opts);;
O
overweight 已提交
126 127
}

L
LiFeng 已提交
128
int graphdriver_create_ro(const char *id, const char *parent, const struct driver_create_opts *create_opts)
O
overweight 已提交
129
{
L
LiFeng 已提交
130 131 132
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
133 134
    }

L
LiFeng 已提交
135 136 137
    if (id == NULL || parent == NULL || create_opts == NULL) {
        ERROR("Invalid input arguments for driver create");
        return -1;
O
overweight 已提交
138 139
    }

L
LiFeng 已提交
140
    return g_graphdriver->ops->create_ro(id, parent, g_graphdriver, create_opts);;
O
overweight 已提交
141 142
}

L
LiFeng 已提交
143
int graphdriver_rm_layer(const char *id)
O
overweight 已提交
144
{
L
LiFeng 已提交
145 146 147
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
148 149
    }

L
LiFeng 已提交
150 151 152
    if (id == NULL) {
        ERROR("Invalid input arguments for driver remove layer");
        return -1;
O
overweight 已提交
153 154
    }

L
LiFeng 已提交
155 156
    return g_graphdriver->ops->rm_layer(id, g_graphdriver);
}
O
overweight 已提交
157

L
LiFeng 已提交
158 159 160 161
char *graphdriver_mount_layer(const char *id, const struct driver_mount_opts *mount_opts)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
O
overweight 已提交
162 163
        return NULL;
    }
L
LiFeng 已提交
164 165 166 167 168 169 170

    if (id == NULL || mount_opts == NULL) {
        ERROR("Invalid input arguments for driver mount layer");
        return NULL;
    }

    return g_graphdriver->ops->mount_layer(id, g_graphdriver, mount_opts);
O
overweight 已提交
171 172
}

L
LiFeng 已提交
173
int graphdriver_umount_layer(const char *id)
174
{
L
LiFeng 已提交
175 176 177
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
178 179
    }

L
LiFeng 已提交
180 181 182
    if (id == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
        return -1;
183 184
    }

L
LiFeng 已提交
185 186
    return g_graphdriver->ops->umount_layer(id, g_graphdriver);
}
187

L
LiFeng 已提交
188 189 190 191 192
bool graphdriver_layer_exists(const char *id)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
193 194
    }

L
LiFeng 已提交
195 196 197
    if (id == NULL) {
        ERROR("Invalid input arguments for driver exists layer");
        return -1;
198
    }
L
LiFeng 已提交
199 200

    return g_graphdriver->ops->exists(id, g_graphdriver);
201 202
}

L
LiFeng 已提交
203
int graphdriver_apply_diff(const char *id, const struct io_read_wrapper *content, int64_t *layer_size)
O
overweight 已提交
204
{
L
LiFeng 已提交
205 206 207 208
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }
O
overweight 已提交
209

L
LiFeng 已提交
210 211
    if (id == NULL || content == NULL || layer_size == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
O
overweight 已提交
212 213 214
        return -1;
    }

L
LiFeng 已提交
215 216 217 218 219 220 221
    return g_graphdriver->ops->apply_diff(id, g_graphdriver, content, layer_size);
}

int graphdriver_get_layer_metadata(const char *id, json_map_string_string *map_info)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
O
overweight 已提交
222 223
        return -1;
    }
L
LiFeng 已提交
224 225 226 227

    if (id == NULL || map_info == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
        return -1;
O
overweight 已提交
228
    }
L
LiFeng 已提交
229 230

    return g_graphdriver->ops->get_layer_metadata(id, g_graphdriver, map_info);
O
overweight 已提交
231 232
}

L
LiFeng 已提交
233
struct graphdriver_status *graphdriver_get_status(void)
O
overweight 已提交
234
{
L
LiFeng 已提交
235 236 237 238 239 240
    int ret = -1;
    struct graphdriver_status *status = NULL;

    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return NULL;
O
overweight 已提交
241
    }
L
LiFeng 已提交
242 243 244 245 246

    status = util_common_calloc_s(sizeof(struct graphdriver_status));
    if (status == NULL) {
        ERROR("Out of memory");
        goto free_out;
O
overweight 已提交
247
    }
L
LiFeng 已提交
248 249 250 251 252

    ret = g_graphdriver->ops->get_driver_status(g_graphdriver, status);
    if (ret != 0) {
        ERROR("Failed to get driver status");
        goto free_out;
O
overweight 已提交
253
    }
L
LiFeng 已提交
254 255 256 257 258

free_out:
    if (ret != 0) {
        free_graphdriver_status(status);
        return NULL;
O
overweight 已提交
259
    }
L
LiFeng 已提交
260
    return status;
O
overweight 已提交
261 262 263 264 265 266 267
}

void free_graphdriver_status(struct graphdriver_status *status)
{
    if (status == NULL) {
        return;
    }
268 269
    free(status->driver_name);
    status->driver_name = NULL;
O
overweight 已提交
270
    free(status->backing_fs);
271
    status->backing_fs = NULL;
W
WangFengTu 已提交
272
    free(status->status);
273
    status->status = NULL;
O
overweight 已提交
274 275 276
    free(status);
}

L
LiFeng 已提交
277 278 279 280 281 282 283 284 285
int graphdriver_cleanup(void)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }

    return g_graphdriver->ops->clean_up(g_graphdriver);
}