Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016, Citrix Systems, Inc.
3 : : *
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions are met:
8 : : *
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 3. Neither the name of the copyright holder nor the names of its
15 : : * contributors may be used to endorse or promote products derived from
16 : : * this software without specific prior written permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 : : * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 : : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 : : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 : : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 : : * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 : : * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : #include "config.h"
33 : : #endif
34 : :
35 : : #include <stdlib.h>
36 : : #include <stdio.h>
37 : :
38 : : #include "tapdisk-driver.h"
39 : : #include "tapdisk-server.h"
40 : : #include "tapdisk-disktype.h"
41 : : #include "tapdisk-stats.h"
42 : :
43 : : static void
44 : 0 : tapdisk_driver_log_flush(td_driver_t *driver, const char *__caller)
45 : : {
46 : 0 : td_loglimit_t *rl = &driver->loglimit;
47 : :
48 [ # # ]: 0 : if (rl->dropped) {
49 : 0 : tlog_syslog(TLOG_WARN,
50 : : "%s: %s: %d messages suppressed",
51 : : driver->name, __caller, rl->dropped);
52 : 0 : rl->dropped = 0;
53 : : }
54 : 0 : }
55 : :
56 : : int
57 : 0 : tapdisk_driver_log_pass(td_driver_t *driver, const char *__caller)
58 : : {
59 : 0 : td_loglimit_t *rl = &driver->loglimit;
60 : 0 : int dropping = rl->dropped;
61 : :
62 [ # # ]: 0 : if (tapdisk_loglimit_pass(rl)) {
63 : 0 : tapdisk_driver_log_flush(driver, __caller);
64 : 0 : return 1;
65 : : }
66 : :
67 [ # # ]: 0 : if (!dropping)
68 : 0 : tlog_syslog(TLOG_WARN,
69 : : "%s: %s: too many errors, dropped.",
70 : : driver->name, __caller);
71 : :
72 : : return 0;
73 : : }
74 : :
75 : : td_driver_t *
76 : 0 : tapdisk_driver_allocate(int type, const char *name, td_flag_t flags)
77 : : {
78 : : int err;
79 : : td_driver_t *driver;
80 : : const struct tap_disk *ops;
81 : :
82 : 0 : ops = tapdisk_disk_drivers[type];
83 [ # # ]: 0 : if (!ops)
84 : : return NULL;
85 : :
86 : 0 : driver = calloc(1, sizeof(td_driver_t));
87 [ # # ]: 0 : if (!driver)
88 : : return NULL;
89 : :
90 : 0 : err = tapdisk_namedup(&driver->name, name);
91 [ # # ]: 0 : if (err)
92 : : goto fail;
93 : :
94 : 0 : driver->ops = ops;
95 : 0 : driver->type = type;
96 : 0 : driver->storage = -1;
97 : 0 : driver->data = calloc(1, ops->private_data_size);
98 [ # # ]: 0 : if (!driver->data)
99 : : goto fail;
100 : :
101 [ # # ]: 0 : if (td_flag_test(flags, TD_USE_NEW_NBD))
102 : : {
103 : 0 : td_flag_set(driver->state, TD_DRIVER_NEW_NBD);
104 : : }
105 : :
106 [ # # ]: 0 : if (td_flag_test(flags, TD_OPEN_RDONLY)){
107 : 0 : td_flag_set(driver->state, TD_DRIVER_RDONLY);
108 : 0 : driver->prep_func = tapdisk_server_prep_tiocb_ro;
109 : 0 : driver->queue_func = tapdisk_server_queue_tiocb_ro;
110 : : } else {
111 : 0 : driver->prep_func = tapdisk_server_prep_tiocb;
112 : 0 : driver->queue_func = tapdisk_server_queue_tiocb;
113 : : }
114 : :
115 : 0 : tapdisk_loglimit_init(&driver->loglimit,
116 : : 16 /* msgs */,
117 : : 90 * 1000 /* ms */);
118 : :
119 : 0 : return driver;
120 : :
121 : : fail:
122 : 0 : free(driver->name);
123 : 0 : free(driver->data);
124 : 0 : free(driver);
125 : 0 : return NULL;
126 : : }
127 : :
128 : : void
129 : 1 : tapdisk_driver_free(td_driver_t *driver)
130 : : {
131 [ - + ]: 1 : if (!driver)
132 : : return;
133 : :
134 [ # # ]: 0 : if (driver->refcnt)
135 : : return;
136 : :
137 [ # # ]: 0 : if (td_flag_test(driver->state, TD_DRIVER_OPEN))
138 : 0 : EPRINTF("freeing open driver %s (state 0x%08x)\n",
139 : : driver->name, driver->state);
140 : :
141 : 0 : tapdisk_driver_log_flush(driver, __func__);
142 : :
143 : 0 : free(driver->name);
144 : 0 : free(driver->data);
145 : 0 : free(driver);
146 : : }
147 : :
148 : : void
149 : 0 : tapdisk_driver_prep_tiocb(td_driver_t *driver, struct tiocb *tiocb, int fd, int rw, char *buf, size_t size,
150 : : long long offset, td_queue_callback_t cb, void *arg)
151 : : {
152 : 0 : driver->prep_func(tiocb, fd, rw, buf, size, offset, cb, arg);
153 : 0 : }
154 : :
155 : : void
156 : 0 : tapdisk_driver_queue_tiocb(td_driver_t *driver, struct tiocb *tiocb)
157 : : {
158 : 0 : driver->queue_func(tiocb);
159 : 0 : }
160 : :
161 : : void
162 : 0 : tapdisk_driver_debug(td_driver_t *driver)
163 : : {
164 [ # # ]: 0 : if (driver->ops->td_debug)
165 : 0 : driver->ops->td_debug(driver);
166 : 0 : }
167 : :
168 : : void
169 : 0 : tapdisk_driver_stats(td_driver_t *driver, td_stats_t *st)
170 : : {
171 : : const disk_info_t *info;
172 : :
173 : 0 : tapdisk_stats_field(st, "type", "d", driver->type);
174 : :
175 : 0 : info = tapdisk_disk_types[driver->type];
176 : 0 : tapdisk_stats_field(st, "name", "s", info->name);
177 : :
178 [ # # ]: 0 : if (driver->ops->td_stats) {
179 : 0 : tapdisk_stats_field(st, "status", "{");
180 : 0 : driver->ops->td_stats(driver, st);
181 : 0 : tapdisk_stats_leave(st, '}');
182 : : } else
183 : 0 : tapdisk_stats_field(st, "status", NULL);
184 : :
185 : 0 : }
|