summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2013-04-17 12:26:58 +0200
committerAndreas Baumann <abaumann@yahoo.com>2013-04-17 12:26:58 +0200
commitc54ea201b80a28fb5285d9c72f012bfda0a3741a (patch)
treee4a18a4b95c014cd79bf4ff7bd4d6b3eed8c4275
parent0ca43761e7ed260055c692d7f2cf804bcaa647b3 (diff)
downloadpgfuse-c54ea201b80a28fb5285d9c72f012bfda0a3741a.tar.gz
pgfuse-c54ea201b80a28fb5285d9c72f012bfda0a3741a.tar.bz2
some first results in statfs, but some sizes are weird, also PGDATA handling is missing
-rw-r--r--config.h8
-rw-r--r--pgfuse.c86
-rw-r--r--schema.sql6
3 files changed, 72 insertions, 28 deletions
diff --git a/config.h b/config.h
index cb83fba..786086e 100644
--- a/config.h
+++ b/config.h
@@ -39,4 +39,12 @@
#define MAX_TABLESPACE_OIDS 16
+/* location of the mtab file of mounted filesystems */
+
+#define MTAB_FILE "/etc/mtab"
+
+/* size of buffer for mtab traversal */
+
+#define MTAB_BUFFER_SIZE 4096
+
#endif
diff --git a/pgfuse.c b/pgfuse.c
index ac42615..f0aa2f6 100644
--- a/pgfuse.c
+++ b/pgfuse.c
@@ -944,6 +944,12 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
int i;
size_t nof_locations = MAX_TABLESPACE_OIDS;
char *location[MAX_TABLESPACE_OIDS];
+ FILE *mtab;
+ struct mntent *m;
+ struct mntent mnt;
+ char strings[MTAB_BUFFER_SIZE];
+ char *prefix;
+ int prefix_len;
if( data->verbose ) {
syslog( LOG_INFO, "Statfs called on '%s', thread #%u",
@@ -961,35 +967,64 @@ static int pgfuse_statfs( const char *path, struct statvfs *buf )
if( res < 0 ) {
return res;
}
+
+ blocks_free = INT64_MAX;
+ blocks_avail = INT64_MAX;
/* iterate over mount entries and try to match to the tablespace locations */
-
-/*
-int main(void) {
- FILE* mtab = setmntent("/etc/mtab", "r");
- struct mntent* m;
- struct mntent mnt;
- char strings[4096];
- while ((m = getmntent_r(mtab, &mnt, strings, sizeof(strings)))) {
- struct statfs fs;
- if ((mnt.mnt_dir != NULL) && (statfs(mnt.mnt_dir, &fs) == 0)) {
- unsigned long long int size = fs.f_blocks * fs.f_bsize;
- unsigned long long int free = fs.f_bfree * fs.f_bsize;
- unsigned long long int avail = fs.f_bavail * fs.f_bsize;
- printf("%s %s size=%lld free=%lld avail=%lld\n",
- mnt.mnt_fsname, mnt.mnt_dir, size, free, avail);
- }
- }
-
- endmntent(mtab);
-}
-*/
+ mtab = setmntent( MTAB_FILE, "r" );
+ while( ( m = getmntent_r( mtab, &mnt, strings, sizeof( strings ) ) ) != NULL ) {
+ struct statfs fs;
+
+ /* skip filesystems without mount point */
+ if( mnt.mnt_dir == NULL ) continue;
+
+ /* skip filesystems which are not a prefix of one of the tablespace locations */
+ prefix = NULL;
+ prefix_len = 0;
+ for( i = 0; i < nof_locations; i++ ) {
+ if( strncmp( mnt.mnt_dir, location[i], strlen( mnt.mnt_dir ) ) == 0 ) {
+ if( strlen( mnt.mnt_dir ) > prefix_len ) {
+ prefix_len = strlen( mnt.mnt_dir );
+ prefix = strdup( mnt.mnt_dir );
+ blocks_free = INT64_MAX;
+ blocks_avail = INT64_MAX;
+ }
+ }
+ }
+ if( prefix == NULL ) continue;
+
+ /* get data of file system */
+ res = statfs( prefix, &fs );
+ if( res < 0 ) {
+ syslog( LOG_ERR, "statfs on '%s' failed: %s, pgfuse mount point '%s', thread #%u",
+ prefix, strerror( errno ), data->mountpoint, THREAD_ID );
+ return res;
+ }
+
+ if( data->verbose ) {
+ syslog( LOG_DEBUG, "Checking mount point '%s' for free disk space, now %jd (%d), was %jd, pgfuse mount point '%s', thread #%u",
+ prefix, fs.f_bfree, fs.f_frsize, blocks_free, data->mountpoint, THREAD_ID );
+ }
+
+ /* take the smallest available disk space free (worst case the first one
+ * to overflow one of the tablespaces)
+ */
+ if( fs.f_bfree * fs.f_frsize < blocks_free * data->block_size ) {
+ blocks_free = fs.f_bfree * fs.f_frsize / data->block_size;
+ }
+ if( fs.f_bavail * fs.f_frsize < blocks_avail * data->block_size ) {
+ blocks_avail = fs.f_bavail * fs.f_frsize / data->block_size;
+ }
+
+ if( prefix ) free( prefix );
+ }
+ endmntent( mtab );
+
for( i = 0; i < nof_locations; i++ ) {
if( location[i] ) free( location[i] );
}
-
- blocks_free = 9999;
-
+
blocks_used = psql_get_fs_blocks_used( conn );
if( blocks_used < 0 ) {
PSQL_ROLLBACK( conn ); RELEASE( conn );
@@ -1025,7 +1060,8 @@ int main(void) {
/* fill statfs structure */
- /* Note: f_frsize, f_favail, f_fsid and f_flag are currently ignored by FUSE */
+ /* Note: blocks have to be retrning as units of f_frsize
+ * f_favail, f_fsid and f_flag are currently ignored by FUSE ? */
buf->f_bsize = data->block_size;
buf->f_frsize = data->block_size;
buf->f_blocks = blocks_total;
diff --git a/schema.sql b/schema.sql
index 2f5c202..555fb25 100644
--- a/schema.sql
+++ b/schema.sql
@@ -24,12 +24,12 @@ CREATE TABLE data (
);
-- create indexes for fast data access
-CREATE INDEX data_dir_id_idx ON data( dir_id );
-CREATE INDEX data_block_no_idx ON data( block_no );
+CREATE INDEX data_dir_id_idx ON data( dir_id ) tablespace test2;
+CREATE INDEX data_block_no_idx ON data( block_no ) tablespace test2;
-- create an index on the parent_id for
-- directory listings
-CREATE INDEX dir_parent_id_idx ON dir( parent_id );
+CREATE INDEX dir_parent_id_idx ON dir( parent_id ) tablespace test2;
-- 16384 == S_IFDIR (S_IFDIR)
-- TODO: should be created by the program after checking the OS