Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / gdplogd / logd_gcl.c @ master

History | View | Annotate | Download (5.9 KB)

1 6b3dbef4 Eric Allman
/* vim: set ai sw=4 sts=4 ts=4 : */
2
3 055d3009 Eric Allman
/*
4
**        ----- BEGIN LICENSE BLOCK -----
5
**        GDPLOGD: Log Daemon for the Global Data Plane
6
**        From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
7
**
8 c87dd166 Eric Allman
**        Copyright (c) 2015-2019, Regents of the University of California.
9 6bd5476b Eric Allman
**        All rights reserved.
10 055d3009 Eric Allman
**
11 6bd5476b Eric Allman
**        Permission is hereby granted, without written agreement and without
12
**        license or royalty fees, to use, copy, modify, and distribute this
13
**        software and its documentation for any purpose, provided that the above
14
**        copyright notice and the following two paragraphs appear in all copies
15
**        of this software.
16 055d3009 Eric Allman
**
17 6bd5476b Eric Allman
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
18
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
19
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
20
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 055d3009 Eric Allman
**
22 6bd5476b Eric Allman
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
23 055d3009 Eric Allman
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 6bd5476b Eric Allman
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
25
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
26
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
27
**        OR MODIFICATIONS.
28 055d3009 Eric Allman
**        ----- END LICENSE BLOCK -----
29
*/
30
31 66474e0a Eric Allman
#include "logd.h"
32 9d11c6da Eric Allman
#include "logd_pubsub.h"
33 6b3dbef4 Eric Allman
34 b0079901 Eric Allman
#if !LOG_CHECK
35 fec93aac Eric Allman
static EP_DBG        Dbg = EP_DBG_INIT("gdplogd.gob", "GDP Log Daemon GOB handling");
36 b0079901 Eric Allman
#endif
37 6b3dbef4 Eric Allman
38
39
/*
40 fec93aac Eric Allman
**  GOB_ALLOC --- allocate a new GOB handle in memory
41 6b3dbef4 Eric Allman
*/
42
43
EP_STAT
44 fec93aac Eric Allman
gob_alloc(gdp_name_t gob_name, gdp_iomode_t iomode, gdp_gob_t **pgob)
45 6b3dbef4 Eric Allman
{
46
        EP_STAT estat;
47 fec93aac Eric Allman
        gdp_gob_t *gob;
48
        extern void gob_close(gdp_gob_t *gob);
49 6b3dbef4 Eric Allman
50
        // get the standard handle
51 fec93aac Eric Allman
        estat = _gdp_gob_new(gob_name, &gob);
52 6b3dbef4 Eric Allman
        EP_STAT_CHECK(estat, goto fail0);
53
54
        // add the gdpd-specific information
55 fc0cbc23 Eric Allman
        gob->x = (struct gdp_gob_xtra *) ep_mem_zalloc(sizeof *gob->x);
56 fec93aac Eric Allman
        if (gob->x == NULL)
57 6b3dbef4 Eric Allman
        {
58
                estat = EP_STAT_OUT_OF_MEMORY;
59
                goto fail0;
60
        }
61 fec93aac Eric Allman
        gob->x->gob = gob;
62 6b3dbef4 Eric Allman
63 fec93aac Eric Allman
        //XXX for now, assume all GOBs are on disk
64 92243bf4 Eric Allman
        gob->x->physimpl = &GdpSqliteImpl;
65 38416c33 Eric Allman
66 235333d5 Eric Allman
        // make sure that if this is freed it gets removed from GclsByUse
67 fec93aac Eric Allman
        gob->freefunc = gob_close;
68 235333d5 Eric Allman
69 6b3dbef4 Eric Allman
        // OK, return the value
70 fec93aac Eric Allman
        *pgob = gob;
71 6b3dbef4 Eric Allman
72
fail0:
73
        return estat;
74
}
75
76
77
/*
78 fec93aac Eric Allman
**  GOB_CLOSE --- close a GDP version of a GOB handle
79 6b3dbef4 Eric Allman
**
80 fec93aac Eric Allman
**                Called from _gdp_gob_freehandle, generally when the reference
81
**                count drops to zero and the GOB is reclaimed.
82 6b3dbef4 Eric Allman
*/
83
84
void
85 fec93aac Eric Allman
gob_close(gdp_gob_t *gob)
86 6b3dbef4 Eric Allman
{
87 fec93aac Eric Allman
        if (gob->x == NULL)
88 bfc817e3 Eric Allman
                return;
89
90 64a0e6ee Eric Allman
        // close the underlying files and free memory as needed
91 fec93aac Eric Allman
        if (gob->x->physimpl->close != NULL)
92
                gob->x->physimpl->close(gob);
93 6b3dbef4 Eric Allman
94 fec93aac Eric Allman
        ep_mem_free(gob->x);
95
        gob->x = NULL;
96 6b3dbef4 Eric Allman
}
97
98 9d11c6da Eric Allman
#if !LOG_CHECK
99 6b3dbef4 Eric Allman
100 f9b45862 Eric Allman
/*
101 4a6db795 Eric Allman
**   GOB_DELETE --- delete and close a GOB
102
*/
103
104
void
105
gob_delete(gdp_gob_t *gob)
106
{
107 a537f186 Eric Allman
        // arrange to remove the GOB from the cache
108
        gob->flags &= ~GOBF_DEFER_FREE;
109
110 4a6db795 Eric Allman
        if (gob->x == NULL)
111
                return;
112
113
        // close the underlying files and free memory as needed
114
        if (gob->x->physimpl->close != NULL)
115
                gob->x->physimpl->close(gob);
116
117
        // now delete the files
118 026f10e4 Eric Allman
        if (gob->x->physimpl->remove != NULL)
119
                gob->x->physimpl->remove(gob);
120 4a6db795 Eric Allman
121
        ep_mem_free(gob->x);
122
        gob->x = NULL;
123
}
124
125
126
/*
127 fec93aac Eric Allman
**  Get an open instance of the GOB in the request.
128 f9b45862 Eric Allman
**
129 fec93aac Eric Allman
**                This maps the GOB name to the internal GOB instance.
130 f9b45862 Eric Allman
**                That open instance is returned in the request passed in.
131 fec93aac Eric Allman
**                The GOB will have it's reference count bumped, so the
132
**                caller must call _gdp_gob_decref when done with it.
133 a8626901 Eric Allman
**
134 fec93aac Eric Allman
**                GOB is returned locked and with its reference count
135 1b7c480e Eric Allman
**                incremented.
136 f9b45862 Eric Allman
*/
137
138 11029b9c Eric Allman
static EP_STAT
139 fec93aac Eric Allman
do_physical_open(gdp_gob_t *gob, void *open_info_)
140 11029b9c Eric Allman
{
141
        EP_STAT estat;
142
143
        if (ep_dbg_test(Dbg, 11))
144 fec93aac Eric Allman
                ep_dbg_printf("do_physical_open: %s\n", gob->pname);
145 11029b9c Eric Allman
146 fc0cbc23 Eric Allman
        gob->x = (struct gdp_gob_xtra *) ep_mem_zalloc(sizeof *gob->x);
147 fec93aac Eric Allman
        gob->x->gob = gob;
148 11029b9c Eric Allman
149 fec93aac Eric Allman
        //XXX for now, assume all GOBs are on disk
150 92243bf4 Eric Allman
        gob->x->physimpl = &GdpSqliteImpl;
151 11029b9c Eric Allman
152
        // make sure that if this is freed it gets removed from GclsByUse
153 fec93aac Eric Allman
        gob->freefunc = gob_close;
154 11029b9c Eric Allman
155
        // open the physical disk files
156 fec93aac Eric Allman
        estat = gob->x->physimpl->open(gob);
157 193627d8 Eric Allman
        if (EP_STAT_ISOK(estat))
158
        {
159 eae1d3ec Eric Allman
                gob->flags |= GOBF_DEFER_FREE;
160
                gob->flags &= ~GOBF_PENDING;
161 193627d8 Eric Allman
        }
162
        else
163 11029b9c Eric Allman
        {
164
                // if this isn't a "not found" error, mark it as an internal error
165
                if (!EP_STAT_IS_SAME(estat, GDP_STAT_NAK_NOTFOUND))
166
                        estat = GDP_STAT_NAK_INTERNAL;
167
        }
168
169
        return estat;
170
}
171
172
173 53393e9c Eric Allman
/*
174
**  Make sure GOB in req->gob is filled in.
175
**
176
**                It must correspond to the address in req->cpdu->dst.
177
**                If req->gob is filled in (i.e., it was NULL on entry), the GOB
178
**                        reference count will be bumped; otherwise it is untouched..
179
*/
180
181 6b3dbef4 Eric Allman
EP_STAT
182 fec93aac Eric Allman
get_open_handle(gdp_req_t *req)
183 6b3dbef4 Eric Allman
{
184
        EP_STAT estat;
185
186 f6eedc78 Eric Allman
        // sanity check
187
        EP_THR_MUTEX_ASSERT_ISLOCKED(&req->mutex);
188
189 11029b9c Eric Allman
        // if we already got this (e.g., in _gdp_pdu_process or in cache),
190 d64e4288 Eric Allman
        //                just let it be
191 fec93aac Eric Allman
        if (req->gob != NULL)
192 6b3dbef4 Eric Allman
        {
193 11029b9c Eric Allman
                estat = EP_STAT_OK;
194 6b3dbef4 Eric Allman
                if (ep_dbg_test(Dbg, 40))
195
                {
196 549b367d Eric Allman
                        gdp_pname_t pname;
197 6b3dbef4 Eric Allman
198 a104a10f Eric Allman
                        gdp_printable_name(req->cpdu->dst, pname);
199 fec93aac Eric Allman
                        ep_dbg_printf("get_open_handle: using existing GOB:\n\t%s => %p\n",
200
                                        pname, req->gob);
201 6b3dbef4 Eric Allman
                }
202
        }
203 11029b9c Eric Allman
        else
204 6b3dbef4 Eric Allman
        {
205 11029b9c Eric Allman
                if (ep_dbg_test(Dbg, 40))
206
                {
207
                        gdp_pname_t pname;
208 d8076087 Eric Allman
209 11029b9c Eric Allman
                        gdp_printable_name(req->cpdu->dst, pname);
210
                        ep_dbg_printf("get_open_handle: finding %s in cache\n", pname);
211
                }
212 f6eedc78 Eric Allman
213
                // it should be safe to unlock the req here, since we should hold the
214
                // only reference, and we need to get the lock ordering right
215
                _gdp_req_unlock(req);
216 fec93aac Eric Allman
                estat = _gdp_gob_cache_get(req->cpdu->dst, GGCF_CREATE, &req->gob);
217 f6eedc78 Eric Allman
                _gdp_req_lock(req);
218 eae1d3ec Eric Allman
                if (EP_STAT_ISOK(estat) && EP_UT_BITSET(GOBF_PENDING, req->gob->flags))
219 4c0ac0eb Eric Allman
                {
220 fec93aac Eric Allman
                        estat = do_physical_open(req->gob, NULL);
221 4c0ac0eb Eric Allman
                        if (EP_STAT_IS_SAME(estat, GDP_STAT_NAK_NOTFOUND))
222
                        {
223
                                // router sent us a reference to a log that we don't own
224
                                _gdp_gob_free(&req->gob);
225
                        }
226
                }
227 fec93aac Eric Allman
                if (!EP_STAT_ISOK(estat) && req->gob != NULL)
228
                        _gdp_gob_decref(&req->gob, false);
229 11029b9c Eric Allman
                if (ep_dbg_test(Dbg, 40))
230
                {
231
                        char ebuf[60];
232 193627d8 Eric Allman
                        gdp_pname_t pname;
233 6b3dbef4 Eric Allman
234 193627d8 Eric Allman
                        gdp_printable_name(req->cpdu->dst, pname);
235 11029b9c Eric Allman
                        ep_stat_tostr(estat, ebuf, sizeof ebuf);
236
                        ep_dbg_printf("get_open_handle: %s => %p: %s\n",
237 fec93aac Eric Allman
                                        pname, req->gob, ebuf);
238 11029b9c Eric Allman
                }
239 6b3dbef4 Eric Allman
        }
240
        return estat;
241
}
242 69c4d71c Eric Allman
243 11029b9c Eric Allman
244 9d11c6da Eric Allman
# endif // LOG_CHECK