Index: trunk/Nebulous/lib/Nebulous/Client.pm
===================================================================
--- trunk/Nebulous/lib/Nebulous/Client.pm	(revision 13278)
+++ trunk/Nebulous/lib/Nebulous/Client.pm	(revision 13302)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Client.pm,v 1.34 2007-05-05 00:14:17 jhoblitt Exp $
+# $Id: Client.pm,v 1.35 2007-05-08 02:27:42 jhoblitt Exp $
 
 package Nebulous::Client;
@@ -257,5 +257,5 @@
 
         $locations = $self->find_instances($key, $vol_name);
-        unless (scalar @{ $locations }) {
+        unless (defined $locations) {
             $log->debug( "no instances" );
             $log->debug( "leaving" );
Index: trunk/Nebulous/lib/Nebulous/Server.pm
===================================================================
--- trunk/Nebulous/lib/Nebulous/Server.pm	(revision 13278)
+++ trunk/Nebulous/lib/Nebulous/Server.pm	(revision 13302)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.40 2007-05-05 02:59:31 jhoblitt Exp $
+# $Id: Server.pm,v 1.41 2007-05-08 02:27:42 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -13,4 +13,5 @@
 
 use DBI;
+use File::ExtAttr qw( setfattr );
 use Log::Log4perl;
 use Nebulous::Server::Config;
@@ -124,5 +125,5 @@
     my $self = shift;
 
-    my ($key, $volume) = validate_pos(@_,
+    my ($key, $vol_name) = validate_pos(@_,
         {
             type        => SCALAR,
@@ -143,15 +144,4 @@
 
     $log->debug( "entered - @_" );
-
-    # Find the storage volume to use.  We are doing this first as there's no
-    # point in creating a new storage object if we can't allocate a new
-    # instance. ->_get_storage_volume() throws an exception on failure.
-    my ($vol_id, $vol_path);
-    eval {
-        ($vol_id, $vol_path) = $self->_get_storage_volume($volume);
-    };
-    if ($@) {
-        $log->logdie($@);
-    }
 
     my $ins_id;
@@ -206,13 +196,9 @@
     # actual on disk file name we can't try to create the file until after
     # we've create both a new storage_storage object and instance.
-    my $filename = $key;
-    # mange '/'s into ':'
-    $filename =~ s|/|:|g;
-    my $uri = URI::file->new("$vol_path/$ins_id.$filename");
-    $log->debug("generated uri $uri");
 
     # TODO add some stuff here to retry if unsucessful
-    eval {
-        _create_empty_file($uri->file, $key);
+    my ($uri, $vol_id);
+    eval {
+        ($uri, $vol_id) = $self->_create_empty_instance_file($key, $ins_id, $vol_name);
     };
     if ($@) {
@@ -220,4 +206,6 @@
         $log->logdie($@);
     }
+
+    $log->debug("created $uri on volume ID: $vol_id");
 
     eval {
@@ -225,8 +213,9 @@
             my $query = $db->prepare_cached( $sql->update_instance_uri );
             # vol_id, uri, ins_id
-            $query->execute($vol_id, $uri, $ins_id);
+            $query->execute($vol_id, "$uri", $ins_id);
         }
 
         $db->commit;
+        $log->debug("commit");
     };
     if ($@) {
@@ -315,12 +304,4 @@
 
     $log->debug("entered - @_");
-
-    my ($vol_id, $vol_path);
-    eval {
-        ($vol_id, $vol_path) = $self->_get_storage_volume($vol_name);
-    };
-    if ($@) {
-        $log->logdie($@);
-    }
 
     my $ins_id;
@@ -361,13 +342,12 @@
     }
 
-    my $filename = $key;
-    # mange '/'s into ':'
-    $filename =~ s|/|:|g;
-    my $uri = URI::file->new("$vol_path/$ins_id.$filename");
-    $log->debug("generated uri $uri");
+    # Unfortunately, since we want to use the instance row's ID as part of the
+    # actual on disk file name we can't try to create the file until after
+    # we've create both a new storage_storage object and instance.
 
     # TODO add some stuff here to retry if unsucessful
-    eval {
-        _create_empty_file($uri->file, $key);
+    my ($uri, $vol_id);
+    eval {
+        ($uri, $vol_id) = $self->_create_empty_instance_file($key, $ins_id, $vol_name);
     };
     if ($@) {
@@ -1107,5 +1087,5 @@
     my $name = shift;
 
-    my ($vol_id, $vol_path);
+    my ($vol_id, $vol_path, $xattr);
     eval {
         # TODO cache this?
@@ -1137,5 +1117,5 @@
 
         my $free;
-        ($vol_id, $vol_path, $free) = $query->fetchrow_array;
+        ($vol_id, $vol_path, $xattr, $free) = $query->fetchrow_array;
         $query->finish;
     };
@@ -1150,5 +1130,5 @@
     $log->debug( "leaving" );
 
-    return ($vol_id, $vol_path);
+    return ($vol_id, $vol_path, $xattr);
 }
 
@@ -1210,4 +1190,77 @@
 }
 
+sub _create_empty_instance_file
+{
+    my $self = shift;
+
+    my ($key, $ins_id, $volume) = @_;
+
+    my $log = $self->log;
+    my $sql = $self->sql;
+    my $db  =$self->db;
+
+    # Find the storage volume to use. 
+    # ->_get_storage_volume() throws an exception on failure.
+    my ($vol_id, $vol_path, $xattr);
+    my ($storage_filename);
+    my ($uri);
+    eval {
+        ($vol_id, $vol_path, $xattr) = $self->_get_storage_volume($volume);
+        $storage_filename = $self->_generate_storage_filename($key, $ins_id);
+        # XXX put a hook for directory hashing here
+        $uri = URI::file->new("$vol_path/$storage_filename");
+        $log->debug("generated uri $uri");
+        $self->_create_empty_file($uri->file);
+    };
+    if ($@) {
+        $log->logdie($@);
+    }
+
+    if ($xattr) {
+        my $path = $uri->file;
+        die "can not set xattr on $path: $!"
+            unless (setfattr($path, 'user.nebulous_key', $key));
+    }
+
+    return ($uri, $vol_id);
+}
+
+
+sub _create_empty_file
+{
+    my $self = shift;
+
+    my ($path) = @_;
+
+    # perl's open() can't do an O_CREAT | O_EXCL
+    die "file $path already exists" if (-e $path);
+
+    my $fh;
+    die "can not open $path: $!"
+        unless (open($fh, '>', $path));
+
+    die "can not close $path: $!"
+        unless (close($fh));
+
+    die "can not chmod $path: $!"
+        unless (chmod 0664, $path);
+
+    return $path;
+}
+
+
+sub _generate_storage_filename
+{
+    my $self = shift;
+
+    my ($key, $ins_id) = @_;
+
+    my $filename = $key;
+    # mangle '/'s into ':'
+    $filename =~ s|/|:|g;
+
+    return "$ins_id.$filename"
+}
+
 
 sub DESTROY
Index: trunk/Nebulous/lib/Nebulous/Server/SQL.pm
===================================================================
--- trunk/Nebulous/lib/Nebulous/Server/SQL.pm	(revision 13278)
+++ trunk/Nebulous/lib/Nebulous/Server/SQL.pm	(revision 13302)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: SQL.pm,v 1.40 2007-05-04 23:36:46 jhoblitt Exp $
+# $Id: SQL.pm,v 1.41 2007-05-08 02:27:42 jhoblitt Exp $
 
 package Nebulous::Server::SQL;
@@ -204,4 +204,5 @@
             vol_id,
             path,
+            xattr,
             total - used as free
         FROM mountedvol
@@ -218,4 +219,5 @@
             vol_id,
             path,
+            xattr,
             total - used as free
         FROM mountedvol
@@ -228,6 +230,6 @@
     },
     new_volume          => qq{
-        INSERT INTO volume (name, path, allocate, available)
-        VALUES (?, ?, TRUE, TRUE)
+        INSERT INTO volume (name, path, allocate, available, xattr)
+        VALUES (?, ?, TRUE, TRUE, FALSE)
     },
     get_volume_by_name => qq{
@@ -359,4 +361,5 @@
     allocate BOOLEAN DEFAULT FALSE,
     available BOOLEAN DEFAULT FALSE,
+    xattr BOOLEAN DEFAULT FALSE,
     PRIMARY KEY(vol_id),
     KEY(name(16)),
@@ -396,4 +399,5 @@
     allocate BOOLEAN DEFAULT FALSE,
     available BOOLEAN DEFAULT FALSE,
+    xattr BOOLEAN DEFAULT FALSE,
     KEY(vol_id),
     KEY(allocate),
@@ -411,6 +415,7 @@
     DECLARE allocatevar BOOLEAN;
     DECLARE availablevar BOOLEAN;
+    DECLARE xattrvar BOOLEAN;
     DECLARE trans_level VARCHAR(255);
-    DECLARE cur1 CURSOR FOR SELECT vol_id, name, path, allocate, available FROM volume;
+    DECLARE cur1 CURSOR FOR SELECT vol_id, name, path, allocate, available, xattr FROM volume;
     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
 
@@ -430,8 +435,8 @@
 
     myloop: LOOP
-        FETCH cur1 INTO vol_idvar, namevar, pathvar, allocatevar, availablevar;
+        FETCH cur1 INTO vol_idvar, namevar, pathvar, allocatevar, availablevar, xattrvar;
         IF `done` THEN LEAVE myloop; END IF;
         INSERT INTO mountedvol
-            SELECT mountpoint, total, used, vol_idvar, namevar, pathvar, allocatevar, availablevar
+            SELECT mountpoint, total, used, vol_idvar, namevar, pathvar, allocatevar, availablevar, xattrvar
             FROM
                 (SELECT *, INSTR(pathvar, mountpoint) = 1 as substring
Index: trunk/Nebulous/lib/Nebulous/Util.pm
===================================================================
--- trunk/Nebulous/lib/Nebulous/Util.pm	(revision 13278)
+++ trunk/Nebulous/lib/Nebulous/Util.pm	(revision 13302)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Util.pm,v 1.6 2007-05-05 02:54:52 jhoblitt Exp $
+# $Id: Util.pm,v 1.7 2007-05-08 02:27:42 jhoblitt Exp $
 
 package Nebulous::Util;
@@ -12,5 +12,4 @@
 use base qw( Exporter );
 
-use File::ExtAttr qw( setfattr );
 use Log::Log4perl qw( :levels );
 use URI::file;
@@ -23,5 +22,4 @@
     _get_filehandle
     _open_uri
-    _create_empty_file
 );
 
@@ -80,27 +78,4 @@
 }
 
-sub _create_empty_file
-{
-    my ($path, $key) = @_;
-
-    # perl's open() can't do an O_CREAT | O_EXCL
-    die "file $path already exists" if (-e $path);
-
-    my $fh;
-    die "can not open $path: $!"
-        unless (open($fh, '>', $path));
-
-    die "can not close $path: $!"
-        unless (close($fh));
-
-    die "can not chmod $path: $!"
-        unless (chmod 0664, $path);
-
-    die "can not set xattr on $path: $!"
-        unless (setfattr($path, 'user.nebulous_key', $key));
-
-    return $path;
-}
-
 1;
 
