Re: [sqlite] [SOLVED] Re: [sqlite] nfs 'sillynames'

2004-09-16 Thread Ara.T.Howard
On Thu, 16 Sep 2004 [EMAIL PROTECTED] wrote:
If this were implemented, it would remove the capability to go into the
background.  A common thing for a daemon process to do upon start-up is to
get everything initialized (e.g. open databases and do other things that
could fail and would need to be reported to the user), and then fork() and
the parent process exits, leaving the child running.
??
do a man 2 fcntl and you'll see:
...
   F_GETFD
  Read  the  close-on-exec  flag.  If the FD_CLOEXEC bit is 0, the
  file will remain open across exec, otherwise it will be  closed.
...
the close-on-exec bit has nothing to do with forking, only exec'ing.  therefore
daemon code would operate exactly as before.  if fact the cose in question IS a
daemon and i'm doing this manually using /proc - but it's not portable.

There's nothing wrong with *either* the parent process continuing to use an
open database handle _or_ the child process continuing to use an open
database handle.  It just can't be used by both, and should be closed by the
one not using it.
sure.  the problem is that, when a fork occurs, the sqlite api may have many
files opens, not only the db handle, such as the db-journal file or
/var/tmp/ files and those files are not exposed to the api client.
therfore they have no reliable way to know which OTHER files to
close/keep-open.  for example:
harp:~ > strace sqlite db 'create table t(f);begin;insert into t values (42);commit;' 
2>&1| grep open | tail
open("/etc/passwd", O_RDONLY)   = 3
open("/home/ahoward/.sqliterc", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/ahoward/db", O_RDWR|O_CREAT|O_LARGEFILE, 0644) = 3
open("/var/tmp/sqlite_ZRnHLHGmAfplF87", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4
open("/home/ahoward/db-journal", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 5
open("/home/ahoward", O_RDONLY|O_LARGEFILE) = 6
open("/var/tmp/sqlite_ZRnHLHGmAfplF87-journal", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 
0600) = 7
open("/var/tmp", O_RDONLY|O_LARGEFILE)  = 8
open("/home/ahoward/db-journal", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 5
open("/home/ahoward", O_RDONLY|O_LARGEFILE) = 6
so here we see that, if a child was created during a transaction it would need
to close quite a few files other than the db itself - it would be nearly
impossible for a client to know which ones to close before execing (not
forking).
Note that if your child does not need the sqlite database handle, it should
call sqlite_close() to release of all resources associated with that handle
(not just close the file).  That should solve your problem.
that IS good advice ;-)  i'll see if that does the trick.  i'm only worried
that closing the database in the child may do something like flush file handles
or commit/abort the current transaction - that would be VERY bad if it occured
in both parent and child.
kind regards.
-a
--
===
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it. 
|   --Dogen
===


Re: [sqlite] [SOLVED] Re: [sqlite] nfs 'sillynames'

2004-09-16 Thread Derrell . Lipman
"Ara.T.Howard" <[EMAIL PROTECTED]> writes:

> the problem is that the child inherits all the open fds from the 'begin
> transaction' (sqlite db-journal, etc.).  in my case, the child never uses
> these at all.  regardless, when the parent does the unlink the sillyname is
> created.
>
> the child could attempt to close this fd, but it's difficult for the child
> to determine which files to close.  i think a better solution would be for
> the sqlite api to set the close-on-exec bit of any files created during a
> transaction - that way a fork/exec will not inherit all those open files.
> in fact - it seem as if setting the close-on-exec bit on ALL files the
> sqlite api opens is the right thing to do since you'd never want them open
> after an exec right?

If this were implemented, it would remove the capability to go into the
background.  A common thing for a daemon process to do upon start-up is to get
everything initialized (e.g. open databases and do other things that could
fail and would need to be reported to the user), and then fork() and the
parent process exits, leaving the child running.

There's nothing wrong with *either* the parent process continuing to use an
open database handle _or_ the child process continuing to use an open database
handle.  It just can't be used by both, and should be closed by the one not
using it.

Note that if your child does not need the sqlite database handle, it should
call sqlite_close() to release of all resources associated with that handle
(not just close the file).  That should solve your problem.

Derrell


[sqlite] [SOLVED] Re: [sqlite] nfs 'sillynames'

2004-09-16 Thread Ara.T.Howard
On Fri, 3 Sep 2004, John LeSueur wrote:
a followup on this post:
i was running some straces on sqlite while it using transactions and think 
i
may have found the source of the problem, we see this in in the strace 
output:

  ...
  ...
  close(5)= 0
  unlink("/dmsp/moby-1-1/ahoward/shared/silly/db-journal") = 0
  ...
  ...
i think what is happening is
  ...
  ...
  close(5)= 0
here remote client opens db-journal
  unlink("/dmsp/moby-1-1/ahoward/shared/silly/db-journal") = 0 
I think this file is created everytime you start a transaction. Maybe even if 
you only perform read only commands.
The journal is what is used to keep track of the changes to the database. 
Anyone else have any thoughts?
this is, of course, the case.  i finally tracked down the cause:  in my code i
do
  begin transaction
  get a job from database
  fork to run job
  update db with pid of job
  commit transation
the problem is that the child inherits all the open fds from the 'begin
transaction' (sqlite db-journal, etc.).  in my case, the child never uses
these at all.  regardless, when the parent does the unlink the sillyname is
created.
the child could attempt to close this fd, but it's difficult for the child to
determine which files to close.  i think a better solution would be for the
sqlite api to set the close-on-exec bit of any files created during a
transaction - that way a fork/exec will not inherit all those open files.  in
fact - it seem as if setting the close-on-exec bit on ALL files the sqlite api
opens is the right thing to do since you'd never want them open after an exec
right?
thoughts?
-a
--
===
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it. 
|   --Dogen
===


Re: [sqlite] nfs 'sillynames'

2004-09-04 Thread Ara.T.Howard
On Fri, 3 Sep 2004, John LeSueur wrote:
I think this file is created everytime you start a transaction. Maybe even
if you only perform read only commands.  The journal is what is used to keep
track of the changes to the database.  Anyone else have any thoughts?
yes - it is.  the thing is, unless a remote client unlinks it while another
client has it open the sillynames would not appear.  i can post a copy of one
of the sillynamed files - but they are definitely the contents of db-journal.
the question is why this is happening.  running strace and looking at the
fcntl lock calls lead me to think it __should__ be impossible for any client
to unlink this file before someone else closed it - but that IS what i'm
seeing happen...
-a
--
===
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it. 
|   --Dogen
===


Re: [sqlite] nfs 'sillynames'

2004-09-03 Thread John LeSueur

a followup on this post:
i was running some straces on sqlite while it using transactions and 
think i
may have found the source of the problem, we see this in in the strace 
output:

  ...
  ...
  close(5)= 0
  unlink("/dmsp/moby-1-1/ahoward/shared/silly/db-journal") = 0
  ...
  ...
i think what is happening is
  ...
  ...
  close(5)= 0
here remote client opens db-journal
  unlink("/dmsp/moby-1-1/ahoward/shared/silly/db-journal") = 0 
I think this file is created everytime you start a transaction. Maybe 
even if you only perform read only commands.
The journal is what is used to keep track of the changes to the 
database. Anyone else have any thoughts?

John LeSueur


Re: [sqlite] nfs 'sillynames'

2004-09-03 Thread Ara.T.Howard
On Fri, 3 Sep 2004, Ara.T.Howard wrote:
if you are unfamiliar with nfs sillynames, they occur when a file that is 
open
on one client is removed or renamed on another.

i am seeing alot of these appear in an NFS directory i'm using to store a
sqlite database acessed by many clients.  the access protocol is a
meta-transaction wrapped around an actual sqlite transaction using an
additional empty lockfile (db.lock).  this is to ensure single writer 
multiple
reader semantics for the entire network, eg.

 lock_type = read  # or perhaps write
 aquire fcntl lock of lock_type on db.lock
   open db.lock
 start_transaction(lock_type)
   db.execute(sql)
 end_transaction
   close db.lock
 release fcntl lock
NONE of the applications has exited for about 30 days.  ALL of the 
application
are aquiring write locks on the db.lock so one process only is accessing the
db.  NONE of the uses removes, renames, etc. the file - only reads and writes
are done via the sqlite api.  the semantics are definitely single writer (and
potentially) many reader, if this we not so the application would crash
horribly almost instantly.  the api i'm using throws an exception if it gets
SQLITE_BUSY and i have no busy handler so i am positive that the locking
works, and that no readers ever attempt to write (upgrade lock) and vice
versa.

i'm simply mystified as to what's creating the sillynames.  they all appear 
to
be the product of the sqlite api: opening them up in vi shows them to be a
binary file that's obviously part of the database since i can recognize many
strings from the database in them.

is worries me - it seems to imply that sqlite, at some point does a rename or
remove when some remote client has an open file handle.  could this be 
because
ALL of my operations (even reads) is inside a transaction?

more info...
the sillynamed files are only ever a minute or so old and disappear almost as
quickly (this would be after the last client called a close).  the 
application
is working great but i'd like to understand this as it concerns me somewhat.
the sqlite lib version is the latest 2.8 branch.  the nfs server/client impl
are the latest patched redhat enterprise versions.

kind regards.
a followup on this post:
i was running some straces on sqlite while it using transactions and think i
may have found the source of the problem, we see this in in the strace output:
  ...
  ...
  close(5)= 0
  unlink("/dmsp/moby-1-1/ahoward/shared/silly/db-journal") = 0
  ...
  ...
i think what is happening is
  ...
  ...
  close(5)= 0
here remote client opens db-journal
  unlink("/dmsp/moby-1-1/ahoward/shared/silly/db-journal") = 0
and the sillyname is created, only to disappear when the remote client closes
the db-journal.
  ...
  ...
the locking seems like it should prevent this - but the files themselves are
definitely subsets of the original - so i'm thinking there is some race
condition here.
-a
--
===
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it. 
|   --Dogen
===