diff --git a/README.md b/README.md index 3560621..fcb0ec1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,39 @@ # udavfs3 Файловая система (FUSE), хранящая данные в базе данных (PostgreSQL) -База данных и пользователь с полным доступом к ней должны быть созданы на сервере. +База данных и пользователь с полным доступом к ней (если их ещё нет) должны быть созданы на сервере: +``` +su - postrges +createuser -S -E -P fs_user +createdb -E UTF-8 -O fs_user fs_db +``` + +Скрипт необходимо скопировать в папку исполняемых файлов (например, /usr/local/bin) и сделать исполняемым: +``` +cp udavfs3 /usr/local/bin/ +chmod +x /usr/local/bin/udavfs3 +``` + +Вручную монтируем следующей командой: +`udavfs3 "host=srv_hostname dbname=fs_db user=fs_user password=fs_user_password" /mount/point/path [-o mount_options]` + +mount_options имеют смысл только для вновь созданной базы данных. +Если мы монтируем уже инициализированную файловую систему, mount_options игнорируются. + +Список опций mount_options: + +* fsid - уникальная (в рамках конкретного сервера) строка без пробелов. Из данной строки сформируется sha1-хэш, который и будет + уникальным идентификатором ФС для операционной системы. +* blocksize - размер блока ФС в байтах. Обычно используется 4096 (4 КБ). +* fssize - размер файловой системы. Можно использовать окончание еденицы измерения (k,m,g,t). Минимальный размер - 4 МБ. + Обратите внимание, что максимальный размер неограничен, но постарайтесь не выйти за пределы свободного места + папки с базой данных сервера PostgreSQL. Или продумайте возможность последующего увеличения размера свободного + места в этой папке до её полного заполнения. + +Если мы хотим, чтобы система монтировала нашу ФС при старте, то добавляем в /etc/fstab следующую строку: + +`udavfs3#"host=srv_hostname dbname=fs_db user=fs_user password=fs_user_password" /mount/point/path fuse _netdev 0 0` + +Чтобы ФС была доступна всем пользователям надо установить 'user_allow_other' в /etc/fuse.conf + +Сервер с базой данных (PostgreSQL) может находиться где угодно. diff --git a/udavfs3 b/udavfs3 index e8c515f..7922eb3 100755 --- a/udavfs3 +++ b/udavfs3 @@ -5,6 +5,7 @@ # UdavFS mount_option: # blocksize= # fssize=[k|m|g|t] +# fsid= # # Option 'user_allow_other' MUST be set in /etc/fuse.conf @@ -500,7 +501,14 @@ class NoSuchRowError(Exception): return 'Query produced 0 result rows' def usage(): - raise SystemExit('Usage: %s "host=dbhost dbname=database user=dbuser password=dbpass" [-o mount_options]\nUdavFS mount_option:\n\tblocksize=\n\tfssize=[k|m|g|t]\n\nOption \'user_allow_other\' MUST be set in /etc/fuse.conf' % sys.argv[0]) + raise SystemExit('''\ +Usage: %s "host=dbhost dbname=database user=dbuser password=dbpass" [-o mount_options] +UdavFS mount_option: + fsid= + blocksize= + fssize=[k|m|g|t] + +Option 'user_allow_other' MUST be set in /etc/fuse.conf''' % sys.argv[0]) if __name__ == '__main__': @@ -510,25 +518,22 @@ if __name__ == '__main__': usage() conn_str = sys.argv[1] options = {x.split('=')[0].strip(): len(x.split('=')) > 1 and x.split('=')[1].strip() or True for x in sys.argv[4].split(',') } - if 'fsname' not in options.keys(): - print('fsname MUST be in mountoptions\n') - usage() - fsname = options['fsname'] - del options['fsname'] - fsid = sha1(bytes(fsname.strip(), 'UTF-8')).hexdigest() db = psycopg2.connect(conn_str) db.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) cursor = db.cursor() try: - cursor.execute('SELECT bs, size FROM fsinfo WHERE fsid=%s', (fsid,)) - blocksize, fssize = cursor.fetchone() + cursor.execute('SELECT fsid, bs, size FROM fsinfo WHERE fsid=%s', (fsid,)) + fsid, blocksize, fssize = cursor.fetchone() except: - if 'create' not in options.keys(): - print('Filesystem "%s" does not exist\n' % (fsname,)) + if 'fsid' not in options.keys(): + print('fsid MUST be in mountoptions\n') usage() - del options['create'] + fsname = options['fsid'] + del options['fsid'] + fsid = sha1(bytes(fsname.strip(), 'UTF-8')).hexdigest() + if 'blocksize' not in options.keys(): print('blocksize mountoption MUST be specified\n') usage() @@ -541,7 +546,7 @@ if __name__ == '__main__': mod1 = {'k': 1024, 'm': 1024 ** 2, 'g': 1024 ** 3, 't': 1024 ** 4} fssize = options['fssize'].lower() del options['fssize'] - if fssize[-1] in mod1.keys(): + if fssize[-1].lower() in mod1.keys(): fssize = math.ceil((int(fssize[:-1]) * mod1[fssize[-1]]) / blocksize) * blocksize if fssize < 4194304: raise SystemExit('Filesystem size less than 4MB.\n') @@ -549,7 +554,7 @@ if __name__ == '__main__': db.close() del db - m_params = [ 'fsname=udavfs', 'nonempty', 'default_permissions', 'allow_other' ] + m_params = [ 'fsname=udavfs3', 'nonempty', 'default_permissions', 'allow_other' ] m_params.extend(options) mountpoint = os.path.abspath(sys.argv[2])