In-progress commit of online cleaner.
[bluesky.git] / bluesky / cleaner.c
1 /* Blue Sky: File Systems in the Cloud
2  *
3  * Copyright (C) 2010  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * TODO: Licensing
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <inttypes.h>
13 #include <glib.h>
14 #include <string.h>
15
16 #include "bluesky-private.h"
17
18 /* Proxy component of the file system cleaner.  This consists effectively of
19  * code for merging multiple versions of the file system logs: that generated
20  * by us and that generated by the in-cloud cleaner.  Other logic, such as for
21  * rewriting log segments where needed and deleting old segments, is handled by
22  * the in-cloud cleaner component. */
23
24 /* Check the cleaner's logs to find the a more recent checkpoint record.  This
25  * should be called occasionally to see if the cleaner has done any work since
26  * our last check. */
27 void bluesky_cleaner_find_checkpoint(BlueSkyFS *fs)
28 {
29     char *prefix = g_strdup_printf("log-%08d", BLUESKY_CLOUD_DIR_CLEANER);
30     char *last_segment = bluesky_store_lookup_last(fs->store, prefix);
31     g_free(prefix);
32     if (last_segment == NULL)
33         return;
34
35     g_print("Last cloud log segment: %s\n", last_segment);
36     int seq = atoi(last_segment + 13);
37     g_free(last_segment);
38
39     if (seq <= fs->log_state->latest_cleaner_seq_seen)
40         return;
41
42     g_print("New log segment appeared in cleaner directory: %d\n", seq);
43
44     BlueSkyCacheFile *cachefile;
45     cachefile = bluesky_cachefile_lookup(fs, BLUESKY_CLOUD_DIR_CLEANER, seq,
46                                          TRUE);
47     while (!cachefile->complete)
48         g_cond_wait(cachefile->cond, cachefile->lock);
49
50     g_print("Downloaded latest cleaner segment.\n");
51
52     int64_t offset = -1, length = 0;
53     while (TRUE) {
54         const BlueSkyRangesetItem *item;
55         item = bluesky_rangeset_lookup_next(cachefile->items, offset + 1);
56         if (item == NULL)
57             break;
58         offset = item->start;
59         length = item->length;
60     }
61
62     if (length > 0) {
63         g_print("Last object: %"PRIu64" + %"PRIu64"\n", offset, length);
64     }
65
66     bluesky_cachefile_unref(cachefile);
67     g_mutex_unlock(cachefile->lock);
68 }