Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / apps / log-mirror.c @ master

History | View | Annotate | Download (3.79 KB)

1 9c59e638 Eric Allman
/* vim: set ai sw=4 sts=4 ts=4 : */
2
3
/*
4
**  LOG-MIRROR --- mirror a log
5
**
6
**                Cheap and dirty replication.
7 055d3009 Eric Allman
**
8
**        ----- BEGIN LICENSE BLOCK -----
9
**        Applications for the Global Data Plane
10
**        From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
11
**
12 c87dd166 Eric Allman
**        Copyright (c) 2015-2019, Regents of the University of California.
13 6bd5476b Eric Allman
**        All rights reserved.
14 055d3009 Eric Allman
**
15 6bd5476b Eric Allman
**        Permission is hereby granted, without written agreement and without
16
**        license or royalty fees, to use, copy, modify, and distribute this
17
**        software and its documentation for any purpose, provided that the above
18
**        copyright notice and the following two paragraphs appear in all copies
19
**        of this software.
20 055d3009 Eric Allman
**
21 6bd5476b Eric Allman
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
22
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
23
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
24
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 055d3009 Eric Allman
**
26 6bd5476b Eric Allman
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
27 055d3009 Eric Allman
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 6bd5476b Eric Allman
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
29
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
30
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
31
**        OR MODIFICATIONS.
32 055d3009 Eric Allman
**        ----- END LICENSE BLOCK -----
33 9c59e638 Eric Allman
*/
34
35
#include <gdp/gdp.h>
36
37
#include <ep/ep_app.h>
38
#include <ep/ep_dbg.h>
39
40
#include <sysexits.h>
41
42
void
43
usage(void)
44
{
45
        fprintf(stderr,
46
                        "Usage: %s [-D dbg_spec] [-G router_addr] source_log target_log\n"
47
                        "    -D  set debugging flags\n"
48
                        "    -G  IP host to contact for gdp_router\n",
49
                        ep_app_getprogname());
50
        exit(EX_USAGE);
51
}
52
53
54
int
55
main(int argc, char **argv)
56
{
57
        int opt;
58
        bool show_usage = false;
59
        EP_STAT estat;
60 eae1d3ec Eric Allman
        gdp_gin_t *igin, *ogin;
61 9c59e638 Eric Allman
        char *gdpd_addr = NULL;
62
        const char *lname, *lmode;
63
        gdp_recno_t nextrecno;
64 eae1d3ec Eric Allman
        gdp_name_t gdpiname;
65 9c59e638 Eric Allman
        gdp_event_t *gev;
66
67
        while ((opt = getopt(argc, argv, "D:G:")) > 0)
68
        {
69
                switch (opt)
70
                {
71
                 case 'D':
72
                        ep_dbg_set(optarg);
73
                        break;
74
75
                 case 'G':
76
                        gdpd_addr = optarg;
77
                        break;
78
79
                 default:
80
                        show_usage = true;
81
                        break;
82
                }
83
        }
84
        argc -= optind;
85
        argv += optind;
86
87
        if (show_usage || argc != 2)
88
                usage();
89
90
        // initialize GDP library
91
        estat = gdp_init(gdpd_addr);
92
        if (!EP_STAT_ISOK(estat))
93
        {
94
                ep_app_error("GDP Initialization failed");
95
                goto fail0;
96
        }
97
98
        // allow thread to settle to avoid interspersed debug output
99
        ep_time_nanosleep(INT64_C(100000000));
100
101
        // open target GCL (must already exist)
102
        lname = argv[1];
103
        lmode = "append";
104 eae1d3ec Eric Allman
        gdp_parse_name(argv[1], gdpiname);
105
        estat = gdp_gin_open(gdpiname, GDP_MODE_AO, NULL, &ogin);
106 9c59e638 Eric Allman
        EP_STAT_CHECK(estat, goto fail1);
107 eae1d3ec Eric Allman
        nextrecno = gdp_gin_getnrecs(ogin) + 1;
108 9c59e638 Eric Allman
109
        // open a source GCL with the provided name
110
        lname = argv[0];
111
        lmode = "read";
112 eae1d3ec Eric Allman
        gdp_parse_name(argv[0], gdpiname);
113
        estat = gdp_gin_open(gdpiname, GDP_MODE_RO, NULL, &igin);
114 9c59e638 Eric Allman
        EP_STAT_CHECK(estat, goto fail1);
115
116
        // subscribe to input starting from the first recno target does not have
117 eae1d3ec Eric Allman
        estat = gdp_gin_subscribe_by_recno(igin, nextrecno, 0, NULL, NULL, NULL);
118 9c59e638 Eric Allman
        EP_STAT_CHECK(estat, goto fail2);
119
120
        // copy forever
121 eae1d3ec Eric Allman
        while ((gev = gdp_event_next(igin, NULL)) != NULL)
122 9c59e638 Eric Allman
        {
123
                switch (gdp_event_gettype(gev))
124
                {
125
                 case GDP_EVENT_DATA:
126
                        // copy the record to the new log
127 eae1d3ec Eric Allman
                        estat = gdp_gin_append(ogin, gdp_event_getdatum(gev), NULL);
128 9c59e638 Eric Allman
                        EP_STAT_CHECK(estat, goto fail3);
129
                        break;
130
131 5ced6d34 Eric Allman
                 case GDP_EVENT_DONE:
132 9c59e638 Eric Allman
                 case GDP_EVENT_SHUTDOWN:
133
                        ep_app_error("unexpected end of subscription");
134
                        estat = EP_STAT_END_OF_FILE;
135
                        goto fail2;
136
137
                 default:
138
                        // ignore
139
                        break;
140
                }
141
        }
142
143
fail3:
144
        ep_app_error("append failed");
145
146
fail2:
147
        // close GCLs / release resources
148
        //XXX someday
149
150
        if (false)
151
        {
152
fail1:
153
                ep_app_error("could not open %s for %s", lname, lmode);
154
        }
155
156
fail0:
157 9829d4ae Eric Allman
        ep_app_message(estat, "exiting with status");
158 9c59e638 Eric Allman
        return EP_STAT_ISOK(estat) ? EX_OK : EX_UNAVAILABLE;
159
}