source: subversion/applications/utils/mod_tile/render_old.c @ 16255

Last change on this file since 16255 was 15864, checked in by jochen, 10 years ago

Fixes to debian scripts

renderd starts in background mode now by default (use -fforeground for old behaviour)
File size: 9.4 KB
Line 
1#define _GNU_SOURCE
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <sys/stat.h>
9#include <sys/time.h>
10#include <sys/un.h>
11#include <poll.h>
12#include <errno.h>
13#include <math.h>
14#include <getopt.h>
15#include <time.h>
16#include <sys/types.h>
17#include <dirent.h>
18#include <limits.h>
19#include <string.h>
20
21#include "gen_tile.h"
22#include "protocol.h"
23#include "render_config.h"
24#include "dir_utils.h"
25
26#ifndef METATILE
27#warning("render_old not implemented for non-metatile mode. Feel free to submit fix")
28int main(int argc, char **argv)
29{
30    fprintf(stderr, "render_old not implemented for non-metatile mode. Feel free to submit fix!\n");
31    return -1;
32}
33#else
34
35#define INILINE_MAX 256
36static int minZoom = 0;
37static int maxZoom = 18;
38static int verbose = 0;
39static int num_render = 0, num_all = 0;
40static time_t planetTime;
41static struct timeval start, end;
42
43
44void display_rate(struct timeval start, struct timeval end, int num) 
45{
46    int d_s, d_us;
47    float sec;
48
49    d_s  = end.tv_sec  - start.tv_sec;
50    d_us = end.tv_usec - start.tv_usec;
51
52    sec = d_s + d_us / 1000000.0;
53
54    printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
55    fflush(NULL);
56}
57
58static time_t getPlanetTime(char *tile_dir)
59{
60    static time_t last_check;
61    static time_t planet_timestamp;
62    time_t now = time(NULL);
63    struct stat buf;
64    char filename[PATH_MAX];
65
66    snprintf(filename, PATH_MAX-1, "%s/%s", tile_dir, PLANET_TIMESTAMP);
67
68    // Only check for updates periodically
69    if (now < last_check + 300)
70        return planet_timestamp;
71
72    last_check = now;
73    if (stat(filename, &buf)) {
74        fprintf(stderr, "Planet timestamp file (%s) is missing\n", filename);
75        // Make something up
76        planet_timestamp = now - 3 * 24 * 60 * 60;
77    } else {
78        if (buf.st_mtime != planet_timestamp) {
79            printf("Planet file updated at %s", ctime(&buf.st_mtime));
80            planet_timestamp = buf.st_mtime;
81        }
82    }
83    return planet_timestamp;
84}
85
86int get_load_avg(void)
87{
88    FILE *loadavg = fopen("/proc/loadavg", "r");
89    int avg = 1000;
90
91    if (!loadavg) {
92        fprintf(stderr, "failed to read /proc/loadavg");
93        return 1000;
94    }
95    if (fscanf(loadavg, "%d", &avg) != 1) {
96        fprintf(stderr, "failed to parse /proc/loadavg");
97        fclose(loadavg);
98        return 1000;
99    }
100    fclose(loadavg);
101
102    return avg;
103}
104
105
106int process_loop(int fd, char * xmlname, int x, int y, int z)
107{
108    struct protocol cmd, rsp;
109    //struct pollfd fds[1];
110    int ret = 0;
111
112    bzero(&cmd, sizeof(cmd));
113
114    cmd.ver = 2;
115    cmd.cmd = cmdRender;
116    cmd.z = z;
117    cmd.x = x;
118    cmd.y = y;
119    strcpy(cmd.xmlname, xmlname);
120    //strcpy(cmd.path, "/tmp/foo.png");
121    //printf("Sending request\n");
122    ret = send(fd, &cmd, sizeof(cmd), 0);
123    if (ret != sizeof(cmd)) {
124        perror("send error");
125    }
126        //printf("Waiting for response\n");
127    bzero(&rsp, sizeof(rsp));
128    ret = recv(fd, &rsp, sizeof(rsp), 0);
129    if (ret != sizeof(rsp)) {
130        perror("recv error");
131        return 0;
132    }
133        //printf("Got response\n");
134
135    if (rsp.cmd != cmdDone) {
136        printf("rendering failed, pausing\n");
137        sleep(10);
138    }
139
140    if (!ret)
141        perror("Socket send error");
142    return ret;
143}
144
145void process(int fd, const char *name)
146{
147    struct stat s;
148    char xmlconfig[XMLCONFIG_MAX];
149    int x, y, z;
150
151    if (path_to_xyz(name, xmlconfig, &x, &y, &z))
152        return;
153
154    num_all++;
155
156//    printf("Found xml(%s) x(%d) y(%d) z(%d)\n", xmlconfig, x, y, z);
157    if ((stat(name, &s) < 0) || (planetTime > s.st_mtime)) {
158         // missing or old, render it
159        printf("Requesting xml(%s) x(%d) y(%d) z(%d)\n", xmlconfig, x, y, z);
160        process_loop(fd, xmlconfig, x, y, z);
161        num_render++;
162        if (!(num_render % 10)) {
163            gettimeofday(&end, NULL);
164            printf("\n");
165            printf("Meta tiles rendered: ");
166            display_rate(start, end, num_render);
167            printf("Total tiles rendered: ");
168            display_rate(start, end, num_render * METATILE * METATILE);
169            printf("Total tiles handled from input: ");
170            display_rate(start, end, num_all);
171        }
172    }
173}
174
175static void check_load(void)
176{
177    int avg = get_load_avg();
178
179    while (avg >= MAX_LOAD_OLD) {
180        printf("Load average %d, sleeping\n", avg);
181        sleep(5);
182        avg = get_load_avg();
183    }
184}
185
186static void descend(int fd, const char *search)
187{
188    DIR *tiles = opendir(search);
189    struct dirent *entry;
190    char path[PATH_MAX];
191
192    if (!tiles) {
193        fprintf(stderr, "Unable to open directory: %s\n", search);
194        return;
195    }
196
197    while ((entry = readdir(tiles))) {
198        struct stat b;
199        char *p;
200
201        check_load();
202
203        if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
204            continue;
205        snprintf(path, sizeof(path), "%s/%s", search, entry->d_name);
206        if (stat(path, &b))
207            continue;
208        if (S_ISDIR(b.st_mode)) {
209            descend(fd, path);
210            continue;
211        }
212        p = strrchr(path, '.');
213        if (p && !strcmp(p, ".meta")) {
214//            printf("Found tile %s\n", path);
215            process(fd, path);
216        }
217    }
218    closedir(tiles);
219}
220
221
222int main(int argc, char **argv)
223{
224    char spath[PATH_MAX] = RENDER_SOCKET;
225    int fd;
226    struct sockaddr_un addr;
227    char *tile_dir = HASH_PATH;
228    int z, c;
229
230    while (1) {
231        int option_index = 0;
232        static struct option long_options[] = {
233            {"min-zoom", 1, 0, 'z'},
234            {"max-zoom", 1, 0, 'Z'},
235            {"socket", 1, 0, 's'},
236            {"tile-dir", 1, 0, 't'},
237            {"verbose", 0, 0, 'v'},
238            {"help", 0, 0, 'h'},
239            {0, 0, 0, 0}
240        };
241
242        c = getopt_long(argc, argv, "hvz:Z:s:t:", long_options, &option_index);
243        if (c == -1)
244            break;
245
246        switch (c) {
247            case 's':   /* -s, --socket */
248                strncpy(spath, optarg, PATH_MAX-1);
249                spath[PATH_MAX-1] = 0;
250                break;
251            case 't':   /* -t, --tile-dir */
252                tile_dir=strdup(optarg);
253                break;
254            case 'z':   /* -z, --min-zoom */
255                minZoom=atoi(optarg);
256                if (minZoom < 0 || minZoom > 18) {
257                    fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and 18\n");
258                    return 1;
259                }
260                break;
261            case 'Z':   /* -Z, --max-zoom */
262                maxZoom=atoi(optarg);
263                if (maxZoom < 0 || maxZoom > 18) {
264                    fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and 18\n");
265                    return 1;
266                }
267                break;
268            case 'v':   /* -v, --verbose */
269                verbose=1;
270                break;
271            case 'h':   /* -h, --help */
272                fprintf(stderr, "Usage: render_old [OPTION] ...\n");
273                fprintf(stderr, "Search the rendered tiles and re-render tiles which are older then the last planet import\n");
274                fprintf(stderr, "  -z, --min-zoom=ZOOM  filter input to only render tiles greater or equal to this zoom level (default 0)\n");
275                fprintf(stderr, "  -Z, --max-zoom=ZOOM  filter input to only render tiles less than or equal to this zoom level (default 18)\n");
276                fprintf(stderr, "  -s, --socket=SOCKET  unix domain socket name for contacting renderd\n");
277                return -1;
278            default:
279                fprintf(stderr, "unhandled char '%c'\n", c);
280                break;
281        }
282    }
283
284    if (maxZoom < minZoom) {
285        fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
286        return 1;
287    }
288
289    fprintf(stderr, "Rendering old tiles\n");
290
291    planetTime = getPlanetTime(tile_dir);
292
293    fd = socket(PF_UNIX, SOCK_STREAM, 0);
294    if (fd < 0) {
295        fprintf(stderr, "failed to create unix socket\n");
296        exit(2);
297    }
298
299    bzero(&addr, sizeof(addr));
300    addr.sun_family = AF_UNIX;
301    strncpy(addr.sun_path, spath, sizeof(addr.sun_path));
302
303    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
304        fprintf(stderr, "socket connect failed for: %s\n", spath);
305        close(fd);
306        exit(3);
307    }
308
309    gettimeofday(&start, NULL);
310
311    FILE * hini ;
312    char line[INILINE_MAX];
313    char value[INILINE_MAX];
314
315    // Load the config
316    if ((hini=fopen(RENDERD_CONFIG, "r"))==NULL) {
317        fprintf(stderr, "Config: cannot open %s\n", RENDERD_CONFIG);
318        exit(7);
319    }
320
321    while (fgets(line, INILINE_MAX, hini)!=NULL) {
322        if (line[0] == '[') {
323            if (strlen(line) >= XMLCONFIG_MAX){
324                fprintf(stderr, "XML name too long: %s\n", line);
325                exit(7);
326            }
327            sscanf(line, "[%[^]]", value);
328
329            for (z=minZoom; z<=maxZoom; z++) {
330                char path[PATH_MAX];
331                snprintf(path, PATH_MAX, HASH_PATH "/%s/%d", value, z);
332                descend(fd, path);
333            }
334        }
335    }
336
337    gettimeofday(&end, NULL);
338    printf("\nTotal for all tiles rendered\n");
339    printf("Meta tiles rendered: ");
340    display_rate(start, end, num_render);
341    printf("Total tiles rendered: ");
342    display_rate(start, end, num_render * METATILE * METATILE);
343    printf("Total tiles handled: ");
344    display_rate(start, end, num_all);
345
346    close(fd);
347    return 0;
348}
349#endif
Note: See TracBrowser for help on using the repository browser.