a2801da1dfc463d93a0b2e3e0000742ad434f816
[cumulus.git] / remote.h
1 /* Cumulus: Smart Filesystem Backup to Dumb Servers
2  *
3  * Copyright (C) 2008  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 /* Backup data (segments and backup descriptors) may be stored on a remote
22  * fileserver instead of locally.  The only local storage needed is for the
23  * local database and some temporary space for staging files before they are
24  * transferred to the remote server.
25  *
26  * Like encryption, remote storage is handled through the use of external
27  * scripts that are called when a file is to be transferred. */
28
29 #ifndef _LBS_REMOTE_H
30 #define _LBS_REMOTE_H
31
32 #include <list>
33 #include <string>
34 #include <pthread.h>
35
36 class RemoteFile;
37
38 class RemoteStore {
39 public:
40     static const size_t MAX_QUEUE_SIZE = 4;
41
42     RemoteStore(const std::string &stagedir);
43     ~RemoteStore();
44     void set_script(const std::string &script)
45         { backup_script = script; }
46     RemoteFile *alloc_file(const std::string &name, const std::string &type);
47     void enqueue(RemoteFile *file);
48     void sync();
49
50 private:
51     pthread_t thread;
52     pthread_mutex_t lock;
53     pthread_cond_t cond;
54
55     std::string staging_dir, backup_script;
56     bool terminate;             // Set when thread should shut down
57     bool busy;                  // True while there are pending transfers
58     std::list<RemoteFile *> transfer_queue;
59
60     /* For error-checking purposes, track the number of files which have been
61      * allocated but not yet queued to be sent.  This should be zero when the
62      * RemoteStore is destroyed. */
63     int files_outstanding;
64
65     void transfer_thread();
66     static void *start_transfer_thread(void *arg);
67 };
68
69 class RemoteFile {
70 public:
71     /* Get the file descriptor for writing to the (staging copy of the) file.
72      * The _caller_ is responsible for closing this file descriptor once all
73      * data is written, and before send() is called. */
74     int get_fd() const { return fd; }
75
76     const std::string &get_local_path() const { return local_path; }
77
78     /* Called when the file is finished--request that it be sent to the remote
79      * server.  This will delete the RemoteFile object. */
80     void send() { remote_store->enqueue(this); }
81 private:
82     friend class RemoteStore;
83
84     RemoteFile(RemoteStore *remote,
85                const std::string &name, const std::string &type,
86                const std::string &local_path);
87
88     RemoteStore *remote_store;
89
90     int fd;
91     std::string type, local_path;
92     std::string remote_path;
93 };
94
95 #endif // _LBS_REMOTE_H