1 /*
2 * Copyright (c) 2007, 2010, XenSource Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of XenSource Inc. nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stddef.h>
30 #include <string.h>
31 #include <errno.h>
32
33 #include "tapdisk-disktype.h"
34 #include "tapdisk-message.h"
35
36 #define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
37
38 static const disk_info_t aio_disk = {
39 "aio",
40 "raw image (aio)",
41 0,
42 };
43
44 static const disk_info_t sync_disk = {
45 "sync",
46 "raw image (sync)",
47 0,
48 };
49
50 static const disk_info_t vmdk_disk = {
51 "vmdk",
52 "vmware image (vmdk)",
53 1,
54 };
55
56 static const disk_info_t vhdsync_disk = {
57 "vhdsync",
58 "virtual server image (vhd) - synchronous",
59 1,
60 };
61
62 static const disk_info_t vhd_disk = {
63 "vhd",
64 "virtual server image (vhd)",
65 0,
66 };
67
68
69 static const disk_info_t ram_disk = {
70 "ram",
71 "ramdisk image (ram)",
72 1,
73 };
74
75 static const disk_info_t qcow_disk = {
76 "qcow",
77 "qcow disk (qcow)",
78 0,
79 };
80
81 static const disk_info_t block_cache_disk = {
82 "bc",
83 "block cache image (bc)",
84 1,
85 };
86
87 static const disk_info_t vhd_index_disk = {
88 "vhdi",
89 "vhd index image (vhdi)",
90 1,
91 };
92
93 static const disk_info_t log_disk = {
94 "log",
95 "write logger (log)",
96 0,
97 };
98
99 static const disk_info_t remus_disk = {
100 "remus",
101 "remus disk replicator (remus)",
102 0,
103 };
104
105 const disk_info_t *tapdisk_disk_types[] = {
106 [DISK_TYPE_AIO] = &aio_disk,
107 [DISK_TYPE_SYNC] = &sync_disk,
108 [DISK_TYPE_VMDK] = &vmdk_disk,
109 [DISK_TYPE_VHDSYNC] = &vhdsync_disk,
110 [DISK_TYPE_VHD] = &vhd_disk,
111 [DISK_TYPE_RAM] = &ram_disk,
112 [DISK_TYPE_QCOW] = &qcow_disk,
113 [DISK_TYPE_BLOCK_CACHE] = &block_cache_disk,
114 [DISK_TYPE_LOG] = &log_disk,
115 [DISK_TYPE_VINDEX] = &vhd_index_disk,
116 [DISK_TYPE_REMUS] = &remus_disk,
117 };
118
119 extern struct tap_disk tapdisk_aio;
120 extern struct tap_disk tapdisk_vhdsync;
121 extern struct tap_disk tapdisk_vhd;
122 extern struct tap_disk tapdisk_ram;
123 extern struct tap_disk tapdisk_qcow;
124 extern struct tap_disk tapdisk_block_cache;
125 extern struct tap_disk tapdisk_log;
126 extern struct tap_disk tapdisk_remus;
127
128 const struct tap_disk *tapdisk_disk_drivers[ARRAY_SIZE(tapdisk_disk_types)] = {
129 [DISK_TYPE_AIO] = &tapdisk_aio,
130 [DISK_TYPE_VHD] = &tapdisk_vhd,
131 [DISK_TYPE_RAM] = &tapdisk_ram,
132 [DISK_TYPE_QCOW] = &tapdisk_qcow,
133 [DISK_TYPE_BLOCK_CACHE] = &tapdisk_block_cache,
134 [DISK_TYPE_LOG] = &tapdisk_log,
135 [DISK_TYPE_REMUS] = &tapdisk_remus,
136 };
137
138 int
tapdisk_disktype_find(const char * name)139 tapdisk_disktype_find(const char *name)
140 {
141 const disk_info_t *info;
142 int i;
143
144 for (i = 0; i < ARRAY_SIZE(tapdisk_disk_types); ++i) {
145 info = tapdisk_disk_types[i];
146 if (!info)
147 continue;
148
149 if (strcmp(name, info->name))
150 continue;
151
152 if (!tapdisk_disk_drivers[i])
153 return -ENOSYS;
154
155 return i;
156 }
157
158 return -ENOENT;
159 }
160
161 int
tapdisk_disktype_parse_params(const char * params,const char ** _path)162 tapdisk_disktype_parse_params(const char *params, const char **_path)
163 {
164 char name[DISK_TYPE_NAME_MAX], *ptr;
165 size_t len;
166 int type;
167
168 ptr = strchr(params, ':');
169 if (!ptr)
170 return -EINVAL;
171
172 len = ptr - params;
173
174 if (len > sizeof(name) - 1)
175 return -ENAMETOOLONG;
176
177 memset(name, 0, sizeof(name));
178 strncpy(name, params, len);
179
180 type = tapdisk_disktype_find(name);
181
182 if (type >= 0)
183 *_path = params + len + 1;
184
185 return type;
186 }
187
188 int
tapdisk_parse_disk_type(const char * params,const char ** _path,int * _type)189 tapdisk_parse_disk_type(const char *params, const char **_path, int *_type)
190 {
191 int type;
192
193 type = tapdisk_disktype_parse_params(params, _path);
194 if (type < 0)
195 return type;
196
197 *_type = type;
198
199 return 0;
200 }
201