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