I have mostly successfully installed Rookchat on my Webserver (SonOS 5.9), and have tried to register a new user. However, if I submit the user data, rookchat drops an exception, stating that a file lock failed because of an invalid file number (if I interpret that correctly). If I comment out the offending line, thus inhibiting the program from locking the file. That seems to help, as I am now able to register the owner, further users etc., but I don't think that it will work correctly if several users are using it at once.
Thus my question: Is there maybe something wrong with locking files on Solaris, and may it indeed cause harm if I suspend file locking that way?
Tanks for help, Stefan
Traceback (most recent call last):
File "index.cgi", line 27, in ?
File "src/rcstart.py", line 38, in ?
controller = controller.Controller()
File "src/controller.py", line 52, in __init__
ret = eval("a." + act + "()")
File "<string>", line 0, in ?
File "src/actions.py", line 55, in register
File "src/banmethods.py", line 50, in is_my_ip_cbanned
File "src/banmethods.py", line 92, in is_ip_cbanned
File "src/rcfiles.py", line 188, in lock
IOError: [Errno 9] Bad file number
That's baffling. Questions:
(1) After you get the exception, go into your rookchat data directory, who is the owner of the "users" subdirectory and what are the file permissions on it?
(2) cd into the "users" subdirectory. Is there a "cbanips" file present?
(3) Try changing config/rc_install_config.py so that "file_permissions" is 2. Remove everything in your rookchat_data directory. Make sure the permissions of that rookchat_data directory are -rwxrwxrwx. Try to register a user again.
You're right that commenting out the flock commands will work for a while but then randomly break sometime down the road when data files are corrupted. I'm not sure if it's Solaris's implementation of flock, though, or if it's just the fact that it can't create and/or open the data files it needs.
The other thing is, since v2.0 just got released today, you might try installing that instead. I don't think it would magically fix your problem, but you never know. :-)
Ad 1: The 'users' subdirectory is owned by unterwes:tumusers (that's myself and the group I've been assigned to). Permissions are 777.
Ad 2: Yes, there's a file 'cbanips'
Ad 3: Been there, done that -- no difference.
The same goes with v. 2.0 (in fact, I've done all the tests with that version).
Could it indeed be some oddness in Solaris' flock? Could I do some tests to be sure of that?
Thanks for your answer and for the great work you've done! :o)
Ok, I'm baffled. Yes, it certainly seems to be Solaris's flock, especially if everything appears to work when you comment out that line, because that rules out not being able to open, read, write, and close the files correctly.
I wish I knew where to go from here, but unfortunately I don't have any idea. I'll snoop around some, ask a friend or two, and see if I can come up with anything.
flock on Solaris is an incomplete emulation using fcntl. The man page itself
"Use of these interfaces should be restricted to only appli-
cations written on BSD platforms. Use of these interfaces
with any of the system libraries or in multi-thread applica-
tions is unsupported."
I suggest you try using fcntl() instead of flock(), at least for Solaris,
and fcntl() is probably a better move in general because it deals better
with NFS filesystems and will be more portable.
Thank you for the suggestion. In fact the man page states that flock is not suited when used over NFS, and my rookchat.data-directory is in fact hosted over NFS.
I've been reading through the relative manpages trying to adjust the particular flock-calls by myself, but I'm far to inexperienced with Python in general and Unix system calls in particular to be able to fix it.
If I understood the manpage correctly, I should substitute the calls to flock(LOCK_UN) and flock(LOCK_EX) with fcntl(F_SETLK,$parameter) and fcntl(F_UNLCK,$parameter). However, that call seems to require an additional parameter, a struct of type flock or something the like. Is there a smooth way to substitute the lock-operations, or would there be little bigger work to be done?
Ok, I finally got around to looking at this. It seems that the correct thing to do is use the lockf() call, which serves as a wrapper for locking fcntl calls. A wrapper appears to be sorely needed, as the lockdata you have to pass into fcntl is tedious to construct and system-dependent besides.
Try making the following changes in the rcfiles.py file, keeping in mind that all indented lines should be indented with tabs, not spaces:
In the "def unlock(file)" function, replace:
from fcntl import flock, LOCK_UN
from fcntl import lockf, LOCK_UN
In the "def lock(file)" function, replace:
from fcntl import flock, LOCK_EX
from fcntl import lockf, LOCK_EX, LOCK_SH
if file.mode == 'r':
Future versions of RookChat will have this new locking code in place.
Substituting the flock()-calls really fixed it. Now it works very well, and everything works just fine.
Thank you for the effort,
Glad to hear it! Cheers.
This is a very sound idea; I'll implement this for the next version. Thanks for solving the mystery!
Thanks in advance.
On a side note: Who had the hilarious idea of providing a latin translation?
That would be the translator himself, Paul Zetler (listed in the credits), who has been a regular reader of RinkWorks for some time now. He goes by Djinn in the forum and chat room there.
I have to agree with you; the idea is hilarious, and I was more than a little excited when he offered to do it.
Sign up for the SourceForge newsletter:
You seem to have CSS turned off.
Please don't fill out this field.