driver.c 7.1 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);

63 64
struct graphdriver *graphdriver_init(const char *name, const char *isulad_root, char **storage_opts,
                                     size_t storage_opts_len)
O
overweight 已提交
65 66
{
    size_t i = 0;
67
    char driver_home[PATH_MAX] = { 0 };
O
overweight 已提交
68

69 70 71 72 73 74 75
    if (name == NULL || storage_opts == NULL || isulad_root == NULL) {
        return NULL;
    }

    int nret = snprintf(driver_home, PATH_MAX, "%s/%s/%s", isulad_root, "storage", name);
    if (nret < 0 || (size_t)nret >= PATH_MAX) {
        ERROR("Sprintf graph driver path failed");
O
overweight 已提交
76 77 78 79 80
        return NULL;
    }

    for (i = 0; i < g_numdrivers; i++) {
        if (strcmp(name, g_drivers[i].name) == 0) {
L
LiFeng 已提交
81 82
            if (g_drivers[i].ops->init(&g_drivers[i], driver_home, (const char **)storage_opts, storage_opts_len) != 0) {
                goto out;
83
            }
L
LiFeng 已提交
84 85 86 87
            g_graphdriver = &g_drivers[i];
            break;
        }
    }
88

L
LiFeng 已提交
89 90 91
out:
    return g_graphdriver;
}
92

L
LiFeng 已提交
93 94 95 96
struct graphdriver *graphdriver_get()
{
    return g_graphdriver;
}
97 98


L
LiFeng 已提交
99
int graphdriver_create_rw(const char *id, const char *parent, struct driver_create_opts *create_opts)
L
LiFeng 已提交
100 101 102 103
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
104 105
    }

L
LiFeng 已提交
106 107 108 109 110 111
    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 已提交
112 113
}

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

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

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

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

L
LiFeng 已提交
136 137 138
    if (id == NULL) {
        ERROR("Invalid input arguments for driver remove layer");
        return -1;
O
overweight 已提交
139 140
    }

L
LiFeng 已提交
141 142
    return g_graphdriver->ops->rm_layer(id, g_graphdriver);
}
O
overweight 已提交
143

L
LiFeng 已提交
144 145 146 147
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 已提交
148 149
        return NULL;
    }
L
LiFeng 已提交
150 151 152 153 154 155 156

    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 已提交
157 158
}

L
LiFeng 已提交
159
int graphdriver_umount_layer(const char *id)
160
{
L
LiFeng 已提交
161 162 163
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
164 165
    }

L
LiFeng 已提交
166 167 168
    if (id == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
        return -1;
169 170
    }

L
LiFeng 已提交
171 172
    return g_graphdriver->ops->umount_layer(id, g_graphdriver);
}
173

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

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

    return g_graphdriver->ops->exists(id, g_graphdriver);
187 188
}

L
LiFeng 已提交
189
int graphdriver_apply_diff(const char *id, const struct io_read_wrapper *content, int64_t *layer_size)
O
overweight 已提交
190
{
L
LiFeng 已提交
191 192 193 194
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }
O
overweight 已提交
195

L
LiFeng 已提交
196 197
    if (id == NULL || content == NULL || layer_size == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
O
overweight 已提交
198 199 200
        return -1;
    }

L
LiFeng 已提交
201 202 203 204 205 206 207
    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 已提交
208 209
        return -1;
    }
L
LiFeng 已提交
210 211 212 213

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

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

L
LiFeng 已提交
219
struct graphdriver_status *graphdriver_get_status(void)
O
overweight 已提交
220
{
L
LiFeng 已提交
221 222 223 224 225 226
    int ret = -1;
    struct graphdriver_status *status = NULL;

    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return NULL;
O
overweight 已提交
227
    }
L
LiFeng 已提交
228 229 230 231 232

    status = util_common_calloc_s(sizeof(struct graphdriver_status));
    if (status == NULL) {
        ERROR("Out of memory");
        goto free_out;
O
overweight 已提交
233
    }
L
LiFeng 已提交
234 235 236 237 238

    ret = g_graphdriver->ops->get_driver_status(g_graphdriver, status);
    if (ret != 0) {
        ERROR("Failed to get driver status");
        goto free_out;
O
overweight 已提交
239
    }
L
LiFeng 已提交
240 241 242 243 244

free_out:
    if (ret != 0) {
        free_graphdriver_status(status);
        return NULL;
O
overweight 已提交
245
    }
L
LiFeng 已提交
246
    return status;
O
overweight 已提交
247 248 249 250 251 252 253 254
}

void free_graphdriver_status(struct graphdriver_status *status)
{
    if (status == NULL) {
        return;
    }
    free(status->backing_fs);
W
WangFengTu 已提交
255
    free(status->status);
O
overweight 已提交
256 257 258
    free(status);
}

L
LiFeng 已提交
259 260 261 262 263 264 265 266 267
int graphdriver_cleanup(void)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }

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