blob: 524fb1d89df35c7e4fddfaf35731ee2c1705aa7b [file] [log] [blame]
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <glib.h>
#include <db.h>
#include "dbfs.h"
struct dbfs *gfs;
void create_db(void)
{
const char *db_home, *db_password;
int rc;
unsigned int flags = 0;
/*
* open DB environment
*/
db_home = getenv("DB_HOME");
if (!db_home) {
fprintf(stderr, "DB_HOME not set\n");
exit(1);
}
/* this isn't a very secure way to handle passwords */
db_password = getenv("DB_PASSWORD");
rc = db_env_create(&gfs->env, 0);
if (rc) {
fprintf(stderr, "gfs->env_create failed: %d\n", rc);
exit(1);
}
gfs->env->set_errfile(gfs->env, stderr);
gfs->env->set_errpfx(gfs->env, "mkdbfs");
if (db_password) {
flags |= DB_ENCRYPT;
rc = gfs->env->set_encrypt(gfs->env, db_password, DB_ENCRYPT_AES);
if (rc) {
gfs->env->err(gfs->env, rc, "gfs->env->set_encrypt");
goto err_out;
}
/* this isn't a very good way to shroud the password */
if (putenv("DB_PASSWORD=X"))
perror("putenv (SECURITY WARNING)");
}
/* init DB transactional environment, stored in directory db_home */
rc = gfs->env->open(gfs->env, db_home,
DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL |
DB_INIT_TXN | DB_CREATE | flags, 0666);
if (rc) {
gfs->env->err(gfs->env, rc, "gfs->env->open");
goto err_out;
}
/*
* Open metadata database
*/
rc = db_create(&gfs->meta, gfs->env, 0);
if (rc) {
gfs->env->err(gfs->env, rc, "db_create");
goto err_out;
}
rc = gfs->meta->open(gfs->meta, NULL, "metadata", NULL,
DB_HASH,
DB_AUTO_COMMIT | DB_CREATE | DB_TRUNCATE | flags,
0666);
if (rc) {
gfs->meta->err(gfs->meta, rc, "gfs->meta->open");
goto err_out_meta;
}
/* our data items are small, so use the smallest possible page
* size. This is a guess, and should be verified by looking at
* overflow pages and other DB statistics.
*/
rc = gfs->meta->set_pagesize(gfs->meta, 512);
if (rc) {
gfs->meta->err(gfs->meta, rc, "gfs->meta->set_pagesize");
goto err_out_meta;
}
/* fix everything as little endian */
rc = gfs->meta->set_lorder(gfs->meta, 1234);
if (rc) {
gfs->meta->err(gfs->meta, rc, "gfs->meta->set_lorder");
goto err_out_meta;
}
return;
err_out_meta:
gfs->meta->close(gfs->meta, 0);
err_out:
gfs->env->close(gfs->env, 0);
exit(1);
}
static void make_root_dir(void)
{
struct dbfs_inode *ino;
guint64 curtime;
int rc;
/* allocate an empty inode */
ino = g_new0(struct dbfs_inode, 1);
ino->raw_ino_size = sizeof(struct dbfs_raw_inode);
ino->raw_inode = malloc(ino->raw_ino_size);
memset(ino->raw_inode, 0, ino->raw_ino_size);
ino->raw_inode->ino = GUINT64_TO_LE(1);
ino->raw_inode->mode = GUINT32_TO_LE(S_IFDIR | 0755);
ino->raw_inode->nlink = GUINT32_TO_LE(2);
curtime = GUINT64_TO_LE(time(NULL));
ino->raw_inode->ctime = curtime;
ino->raw_inode->atime = curtime;
ino->raw_inode->mtime = curtime;
rc = dbfs_inode_write(ino);
if (rc)
goto err_die;
rc = dbfs_dir_new(1, 1, ino);
if (rc)
goto err_die;
dbfs_inode_free(ino);
return;
err_die:
errno = -rc;
perror("dbfs_inode_write");
exit(1);
}
int main (int argc, char *argv[])
{
gfs = dbfs_new();
create_db();
make_root_dir();
dbfs_close(gfs);
return 0;
}