Storing files off-site with gmail
Posted by Steve on Fri 29 Jul 2005 at 02:18
gmail is the well-known webmail service from Google. Whilst I've never really used it for mail I do mount its storage space, remotely, upon my Debian machine and use it as another form of backup space.
The trick to doing this is the gmailfs package. This takes advantage of filesystem in userspace (fuse) project.
Fuse, as its name suggests, allows you to code a filesystem entirely in user-space - no kernel mode programming required. With a little bit of effort you can treat almost anything as a filesystem.
The gmailfs module allows you to treat GMail's storage space as a mountable filesystem. It is not the fastest thing on the world, and Google may well remove the ability to use it in the future, but right now it works nicely.
Other approaches to mounting remote systems include:
To get started you'll need to download and install the gmailfs package via apt-get (or aptitude):
root@sillyhostname:~# apt-get install gmailfs Reading package lists... Done Building dependency tree... Done The following extra packages will be installed: fuse-utils libfuse2 python-fuse python-libgmail python2.3-fuse Suggested packages: fuse-module The following NEW packages will be installed: fuse-utils gmailfs libfuse2 python-fuse python-libgmail python2.3-fuse 0 upgraded, 6 newly installed, 0 to remove and 1 not upgraded. Need to get 141kB of archives. After unpacking 532kB of additional disk space will be used. Do you want to continue [Y/n]?
Once installed the package will prompt you, via debconf, which group should be given permission to run several commands. You may choose the default option for this question safely.
The next step is to build and install the fuse kernel module.
To do this you'll need to download the fuse-source package, along with module-assistant if you don't already have that installed.
The module-assistant package is a great tool to build kernel modules for Debian systems.
root@sillyhostname:# apt-get install fuse-source Reading package lists... Done Building dependency tree... Done Suggested packages: kernel-package The following NEW packages will be installed: fuse-source 0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. Need to get 83.7kB of archives. After unpacking 127kB of additional disk space will be used.
Now that the packages are ready you can build the kernel module by executing the following three commands:
root@sillyhostname:~# module-assistant prepare Kernel headers available in /usr/src/linux Done! root@sillyhostname:~# module-assistant build fuse root@sillyhostname:~# module-assistant install fuse
This should build and install a package which contains the kernel module. To actually load the kernel module execute:
root@sillyhostname:~# modprobe fuse
If you receive an error message:
FATAL: Error inserting fuse : Invalid module format
This most probably means that the compiler you are using to build the kernel module doesn't match the one used to build the kernel you are running. You can discover the GCC version used to compile your kernel by running "cat /proc/version". A simple solution here to run the following commands, assuming that your kernel was built with gcc-3.3 as mine was:
root@sillyhostname:# cd /usr/src/modules/fuse/kernel root@sillyhostname:# rm .*.cmd *.o *.ko root@sillyhostname:# rm /usr/bin/gcc; ln -s /usr/bin/gcc-3.3 /usr/bin/gcc root@sillyhostname:# module-assistant build fuse --force root@sillyhostname:# module-assistant install fuse --force
Once you've successfully built and installed the kernel module you can start to mount your remote gmail space. (Don't forget you must have a gmail account already setup!)
To mount the filesystem you need four things:
- The gmail login.
- The gmail password.
- A directory to mount the filesystem upon.
- A "random string"
The random string is very important. You must choose something random as a kind of key when mounting the remote system. If you choose something that somebody else can guess they are capable of messing up your filesystem by sending you malicious email.
To actually mount the filesystem first create a mount-point:
root@sillyhostname:~# mkdir -p /mnt/google
Then mount it with the following command:
root@sillyhostname:~# mount -t gmailfs none /mnt/google -o username=username@gmail.com,password=Password,fsname=Key
root@sillyhostname:~#
gmailfs.py:Gmailfs:mountpoint: '/mnt/google'
gmailfs.py:Gmailfs:unnamed mount options: ['rw']
gmailfs.py:Gmailfs:named mount options: {'username': 'username@gmail.com', 'password': 'password', 'fsname': 'key'}
INFO:gmailfs:Connected to gmail
Here I've used a bold font for the parts you should replace. Once you've ran this command you'll be returned to your prompt after a short delay. (Strangely I had to press 'Return' to get a prompt back...)
Now you can copy files to the mountpoint, /mnt/google, which will result in files being created remotely. You'll notice that the speed is much slower than a local access, but in all other respects it should work as a normal filesystem.
To disconnect the remote mount run:
umount /mnt/google
If you view your gmail webmail you will discover lots of "random" mail messages sent to yourself, from you. These are the contents of your filesystem - delete them and your file store will be gone!
If you wish you can setup the username and password in the file /etc/gmailfs/gmailfs.conf - this file allows you to store your gmail username, password, and key.
If you do store your connection details you can mount the system by executing simply:
root@sillyhostname:# mount.gmailfs none /mnt/google -o
All mount and unmount operations conducted over the gmailfs filesystem will be logged to the file /var/log/gmailfs, which can be used to diagnose errors. To increase the level of debugging information simply adjust the configuration file /etc/gmailfs/gmailfs.conf appropriately.
All in all the system allows a reasonably reliable system for storing non-essential backups. I'd be wary of trusting the storage too much, but if your files are non-critical have a blast!
[ Parent | Reply to this comment ]
It solves a problem that no-one seems to notice- that the majority of off-site backups (including this "backing up to GMail" article) completely ignore the fact that the remote machine is untrusted.
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
I tend to assume that this is implicit with off-site backups. But it's certainly worth highlighting, and I'll be careful to do so in the future.
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
But, when I try to mount on my Ubuntu, I have the folowing error:
"fusermount: old style mounting not supported"
This error seems common on Ubuntu, but I didn't found someone providing a step by step to correct it...Anyone here? :)
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
Are you running as root?
Are you running mount.gmailfs or mount? fusermount isn't something that I've ever ran by itself...
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
yannick@central:~$ sudo mount -t gmailfs none /mnt/gmail/ -o username=xx@gmail.com,password=xx,fsname=xx
fusermount: old style mounting not supported
yannick@central:~$
Thank you
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
I'm sorry I can't see why that doesn't work.
That works perfectly for me when I add in my details.
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
I know the problem is with Ubuntu and some packages versions inside the distro..(searched on ubuntu forum and every people have the same error)..
I just asked..if any Linux/Debian/Ubuntu gurus read this..?.. :)
Thank you :)
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
[ Parent | Reply to this comment ]
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol misc_deregister_R730d885c
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol igrab_R7b109932
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol page_hash_table_Rf1b865b8
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol is_bad_inode_Rb49eab45
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol generic_file_llseek_R78c1ef4b
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol invalidate_inode_pages_R0cff645a
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol lock_page_R2fed7051
/lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: /lib/modules/2.4.27-2-386/kernel/fs/fuse/fuse.o: unresolved symbol make_bad_inode_R4952d6b9
etc...
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
Strange, I assumed it would work for kernel 2.4.x - I wonder if that's where the problem is coming from?
Either that or some modules not being loaded which it's relying upon.
What happens if you use modprobe rather than insmod?
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
13:02:42 root@devel:~\ $mount.gmailfs none /mnt/gmail/ -o
13:02:43 root@devel:~\ $Traceback (most recent call last):
File "/usr/share/gmailfs/gmailfs.py", line 28, in ?
import libgmail
File "/usr/lib/python2.3/site-packages/libgmail/__init__.py", line 34, in ?
import urllib2
File "/usr/lib/python2.3/urllib2.py", line 93, in ?
import httplib
File "/usr/lib/python2.3/httplib.py", line 70, in ?
import mimetools
File "/usr/lib/python2.3/mimetools.py", line 6, in ?
import tempfile
File "/usr/lib/python2.3/tempfile.py", line 33, in ?
from random import Random as _Random
File "/usr/lib/python2.3/random.py", line 42, in ?
from math import log as _log, exp as _exp, pi as _pi, e as _e
ImportError: /usr/lib/python2.3/lib-dynload/math.so: undefined symbol: PyFPE_jbuf
[ Parent | Reply to this comment ]
i successfully installed gmailfs , fuse , mounted gmail, moved a textfile there, and even read it back once, but when I tried to open it up with vim I got
utumno:/mnt# ls -l
Traceback (most recent call last):
File "/usr/share/gmailfs/gmailfs.py", line 316, in setInode
subject = self.inode_msg.subject
AttributeError: 'NoneType' object has no attribute 'subject'
ls: sel: Invalid argument
total 0
I then manually removed all FS messages from my GMail account , tried one more time, it seemed to work but when I unmounted and re-mounted, I got the above error again :(
[ Parent | Reply to this comment ]
utumno:/mnt/test# echo aaaaa > file.txt
utumno:/mnt/test# cat file.txt
aaaaa
utumno:/mnt/test# Traceback (most recent call last):
File "/usr/lib/python2.3/site-packages/fuse.py", line 40, in __call__
return apply(self.func, args, kw)
File "/usr/share/gmailfs/gmailfs.py", line 1020, in release
del self.openfiles[path]
KeyError: '/test/file.txt'
[ Parent | Reply to this comment ]
and i get a Permission denied error
ex:
coolbook@debook:/mnt$ cd /mnt/gmail
bash: cd: /mnt/gmail: Permission denied
But,i was as root account successfully used gmailfs
i had done this command chmod -R 777 /mnt/gmail
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Traceback (most recent call last):
File "/usr/share/gmailfs/gmailfs.py", line 1117, in ?
server = Gmailfs()
File "/usr/share/gmailfs/gmailfs.py", line 603, in __init__
self.ga.login()
File "/usr/lib/python2.3/site-packages/libgmail/__init__.py", line 271, in login
pageData = self._retrievePage(req)
File "/usr/lib/python2.3/site-packages/libgmail/__init__.py", line 296, in _retrievePage
resp = urllib2.urlopen(req)
File "/usr/lib/python2.3/urllib2.py", line 129, in urlopen
return _opener.open(url, data)
File "/usr/lib/python2.3/urllib2.py", line 326, in open
'_open', req)
File "/usr/lib/python2.3/urllib2.py", line 306, in _call_chain
result = func(*args)
File "/usr/lib/python2.3/urllib2.py", line 908, in https_open
return self.do_open(httplib.HTTPS, req)
File "/usr/lib/python2.3/urllib2.py", line 886, in do_open
raise URLError(err)
urllib2.URLError:
[ Parent | Reply to this comment ]
Just type:
m-a a-i fuse
(where m-a stands for module-assistant and a-i means auto-install), and it does all the job for you !
Just my 2¢...
[ Parent | Reply to this comment ]
Traceback (most recent call last): File "/usr/share/gmailfs/gmailfs.py", line 1117, in ? server = Gmailfs() File "/usr/share/gmailfs/gmailfs.py", line 603, in __init__ self.ga.login() File "/usr/lib/python2.4/site-packages/libgmail/__init__.py", line 281, in login raise GmailLoginFailure libgmail.GmailLoginFailureany clues?
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
11/06/05 10:33:34 WARNING OpenSSLProxy is missing. HTTPS proxy support disabled.
Unfortunatley, I don't know enough about OpenSSL to get anywhere with the error but I'm not going through a proxy.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Follow the instructions on the official GmailFS site : http://richard.jones.name/google-hacks/gmail-filesystem/gmail-fil esystem.html.
Make sure you get the latest libgmail with cvs.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
mount.gmailfs none /mnt/gmail -o username=username,password=passwordstring,fsname=linux_fs_3
No messages found
Traceback (most recent call last):
File "/usr/share/gmailfs/gmailfs.py", line 241, in __init__
matchInode = m.group(2)
AttributeError: 'NoneType' object has no attribute 'group
any ideas?
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
GMail has moved on. Look at the bugs reported against the package ..
[ Parent | Reply to this comment ]
All the install goes smothlly but when i mount, i ve got an error :
lapbdu:/mnt# mount.gmailfs none /mnt/google
fusermount: failed to open /dev/fuse: No such file or directory
fuse: reading device: Bad file descriptor
lapbdu:/mnt#
I don't know what i can do...
Thanks
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
gmailfs did not connect in less than 12 seconds... i am sure that my gmail's username and password is correct... does someone have any solution about this?
Here is the details of the ~/gmailfs.log
02/09/06 14:24:48 ERROR OpenSSLProxy is missing. Can't use HTTPS proxy!
02/09/06 14:24:48 INFO waiting for /mnt/google to become a mountpoint
02/09/06 14:24:48 INFO Starting gmailfs in child process (PID 17861)
02/09/06 14:24:48 INFO Mountpoint: /mnt/google
02/09/06 14:24:48 INFO Unnamed mount options: ('/mnt/google',)
02/09/06 14:24:48 INFO Named mount options: {'username': 'dddan0001', 'password': ''}
02/09/06 14:24:48 WARNING mount: warning, should mount with fsname=name option, using default
02/09/06 14:25:00 ERROR gmailfs did not connect in less than 12 seconds, aborting...
02/09/06 14:25:02 WARNING Child process 17861 received SIGHUP, exiting...
02/09/06 14:25:02 INFO Successfully reaped child 17861
[ Parent | Reply to this comment ]
aptitude install python2.3-pyopenssl
and
http://richard.jones.name/google-hacks/gmail-filesystem/pyOpenSSL Proxy-0.1.tar.gz
(there is no this package in debian now)
--
Apels1n
[ Parent | Reply to this comment ]
But it worth to be mentioned, that mount.gmailfs has one important optional parameter - -p, --prompt-for-password. It allows not to disclose password via config files or commandline history.
I've installed fuse-utils, added myself to 'fuse' group, edited and copied /etc/gmailfs/gmailfs.conf to ~/.gmailfs, created mount dir in home directory and launched as normal user:
$ /sbin/mount.gmailfs -p /usr/share/gmailfs/gmailfs.py ~/gmailfs
and it works perfectly ;-)
To umount:
$ fusermount -u ~/gmailfs
[ Parent | Reply to this comment ]
Ignored option :rw
HTTP Error 400: Bad Request
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/gmailfs.py", line 193, in _sendMessage
if ga.sendMessage(gmsg):
File "/usr/lib/python2.4/site-packages/libgmail.py", line 531, in sendMessage
params = {U_VIEW: [u_sendmail_view, u_savedraft_view][asdraft],
File "/usr/lib/python2.4/site-packages/libgmail.py", line 511, in _getActionToken
at = self._cookieJar._cookies[action_token_cookie]
KeyError: 'GMAIL_AT'
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/gmailfs.py", line 193, in _sendMessage
if ga.sendMessage(gmsg):
File "/usr/lib/python2.4/site-packages/libgmail.py", line 531, in sendMessage
params = {U_VIEW: [u_sendmail_view, u_savedraft_view][asdraft],
File "/usr/lib/python2.4/site-packages/libgmail.py", line 511, in _getActionToken
at = self._cookieJar._cookies[action_token_cookie]
KeyError: 'GMAIL_AT'
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/gmailfs.py", line 193, in _sendMessage
if ga.sendMessage(gmsg):
File "/usr/lib/python2.4/site-packages/libgmail.py", line 531, in sendMessage
params = {U_VIEW: [u_sendmail_view, u_savedraft_view][asdraft],
File "/usr/lib/python2.4/site-packages/libgmail.py", line 511, in _getActionToken
at = self._cookieJar._cookies[action_token_cookie]
KeyError: 'GMAIL_AT'
with the lines from Traceback to 'GMAIL_AT' 33 more times, after which the program runs stuck & doesn't exit unless I press CTRL+C, after which the following message appears:
Traceback (most recent call last):
File "/sbin/mount.gmailfs", line 166, in ?
pee-tor:/home/ppp# main(mountpoint, namedOptions, useEncfs)
File "/sbin/mount.gmailfs", line 115, in main
os.waitpid(gmailfsPID, 0) # upon receiving SIGHUP, it should exit, so we block-wait on it
KeyboardInterrupt
...and exits. Using Debian Etch & got gmailfs by apt-get. Help, anyone?
[ Parent | Reply to this comment ]
hangs and doesnt mount.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
From Gmail Help senter:
Third party applications and Gmail
Using third party software applications that interact with Gmail directly violates the Terms of Use that all users must agree to before creating a Gmail address.
[ Parent | Reply to this comment ]