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_OPEN_RDONLY)){
102 : 0 : td_flag_set(driver->state, TD_DRIVER_RDONLY);
103 : 0 : driver->prep_func = tapdisk_server_prep_tiocb_ro;
104 : 0 : driver->queue_func = tapdisk_server_queue_tiocb_ro;
105 : : } else {
106 : 0 : driver->prep_func = tapdisk_server_prep_tiocb;
107 : 0 : driver->queue_func = tapdisk_server_queue_tiocb;
108 : : }
109 : :
110 : 0 : tapdisk_loglimit_init(&driver->loglimit,
111 : : 16 /* msgs */,
112 : : 90 * 1000 /* ms */);
113 : :
114 : 0 : return driver;
115 : :
116 : : fail:
117 : 0 : free(driver->name);
118 : 0 : free(driver->data);
119 : 0 : free(driver);
120 : 0 : return NULL;
121 : : }
122 : :
123 : : void
124 : 2 : tapdisk_driver_free(td_driver_t *driver)
125 : : {
126 [ - + ]: 2 : if (!driver)
127 : : return;
128 : :
129 [ # # ]: 0 : if (driver->refcnt)
130 : : return;
131 : :
132 [ # # ]: 0 : if (td_flag_test(driver->state, TD_DRIVER_OPEN))
133 : 0 : EPRINTF("freeing open driver %s (state 0x%08x)\n",
134 : : driver->name, driver->state);
135 : :
136 : 0 : tapdisk_driver_log_flush(driver, __func__);
137 : :
138 : 0 : free(driver->name);
139 : 0 : free(driver->data);
140 : 0 : free(driver);
141 : : }
142 : :
143 : : void
144 : 0 : tapdisk_driver_prep_tiocb(td_driver_t *driver, struct tiocb *tiocb, int fd, int rw, char *buf, size_t size,
145 : : long long offset, td_queue_callback_t cb, void *arg)
146 : : {
147 : 0 : driver->prep_func(tiocb, fd, rw, buf, size, offset, cb, arg);
148 : 0 : }
149 : :
150 : : void
151 : 0 : tapdisk_driver_queue_tiocb(td_driver_t *driver, struct tiocb *tiocb)
152 : : {
153 : 0 : driver->queue_func(tiocb);
154 : 0 : }
155 : :
156 : : void
157 : 0 : tapdisk_driver_debug(td_driver_t *driver)
158 : : {
159 [ # # ]: 0 : if (driver->ops->td_debug)
160 : 0 : driver->ops->td_debug(driver);
161 : 0 : }
162 : :
163 : : void
164 : 0 : tapdisk_driver_stats(td_driver_t *driver, td_stats_t *st)
165 : : {
166 : : const disk_info_t *info;
167 : :
168 : 0 : tapdisk_stats_field(st, "type", "d", driver->type);
169 : :
170 : 0 : info = tapdisk_disk_types[driver->type];
171 : 0 : tapdisk_stats_field(st, "name", "s", info->name);
172 : :
173 [ # # ]: 0 : if (driver->ops->td_stats) {
174 : 0 : tapdisk_stats_field(st, "status", "{");
175 : 0 : driver->ops->td_stats(driver, st);
176 : 0 : tapdisk_stats_leave(st, '}');
177 : : } else
178 : 0 : tapdisk_stats_field(st, "status", NULL);
179 : :
180 : 0 : }
|