Learning more about descriptors...
Posted by Nick Cash
on Sun 19 Jan 2003 04:31 AM
— 29 posts, 90,743 views.
I really am a newbie coder that just learned how to do everything by messing with it and figuring out what it meant(and reading some books on C coding, but I believe you don't get the gist of coding till you have really messed with some code). Anyways, I was reading about the entire descriptor deal and I was just saying to myself "Hey, I've looked through that code, but I don't really under stand what it all means.." So, yeah, if you would could you explain in short what descriptors in the MUD are really about, becaue all I know is that you need them to log on and everything.
The second thing I have to say is how nice I think it is that everyone is so helpful on this forum. I think its great we can just post our problems with our code and have other people that are kind enough to help up figure it out. Anyways, I just thought i would say thanks to anyone and everyone who reads, posts, admin's this forum.
Thanks for everything.
When you open a file, or create a TCP/IP connection with a socket, the operating system gives you a number, which is its internal reference to that file. This can be called a file descriptor (I think Windows calls it a handle, but a rose by any other name ...).
You subsequently use this descriptor to access the file (eg. read, write, close, query, etc.). The operating system looks it up in its internal table to see which file you are talking about.
In SMAUG, which is mainly TCP/IP I/O (plus some disk files) the term descriptor generally refers to a connected player, and hence the file descriptor returned by the OS when the connection is established. Somewhat confusingly the low-level operating system descriptor is stored in an internal structure called descriptor_data, which stores the OS descriptor, plus other things that are useful, such as incoming data that hasn't been processed yet (eg. because no linefeed), outgoing data yet to be sent, and so on.
See mud.h for that structure.
And by the way, thanks for the compliments about the forum. Glad you find it useful. :)
A little more info on descriptors..
In a native *nix environment you can see what descriptors a particular program may have open quite easily.
First type 'ps x' You'll get a list of processes your shell user has running. It'll look like a list of these:
15728 pts/12 S 0:01 gdb ../src/smaug
That first number is your pid (Process Id). With that number on hand, change to your /proc directory.
Typing 'ls' you'll see an extensive list of numbers and other seemingly cryptic things. One of those numbers will correspond to your mud's pid. It is in fact, a directory. Change to that directory. In this case, I would type 'cd 15728'.
You'll enter another directory full of files all related to that pid. One of those directories is called 'fd'. Change to that directory. Within that directory will be a *hopefully* medium range of numbers. Each one of those numbers represents a file descriptor your mud is using. It could be a file the mud has open or a 'socket' that's open (someone who's connected). There are also a number of system reserved/used file descriptors.
Typing 'ls -l' will give you a more detailed listing. Like such:
[thresher@users: fd]$ ls -l
total 0
lrwx------ 1 thresher users 64 Jan 19 00:15 0 -> /dev/pts/4 (deleted)
l-wx------ 1 thresher users 64 Jan 19 00:15 1 -> /home/thresher/smaug/dist/log/122.log
lrwx------ 1 thresher users 64 Jan 19 00:15 10 -> socket:[2733641]
l-wx------ 1 thresher users 64 Jan 19 00:15 2 -> /home/thresher/smaug/dist/log/122.log
lr-x------ 1 thresher users 64 Jan 19 00:15 3 -> /dev/null
lr-x------ 1 thresher users 64 Jan 19 00:15 4 -> /dev/null
lrwx------ 1 thresher users 64 Jan 19 00:15 5 -> socket:[2726550]
lrwx------ 1 thresher users 64 Jan 19 00:15 8 -> socket:[2734964]
[thresher@users: fd]$
Looking at this you can see what files the process has open currently and the number of sockets connected. You'll notice that the number listed here corresponds to the descriptor number of a connected user.
This list can also be very handy in tracking down potential 'descriptor leaks'. A descriptor leak is caused by the program opening a file but not closing it. If you see a list of files here pointing at player files for example. You likely have a problem somewhere.
I hope this has expanded your knowledge of descriptors a bit. More then likely I just confused you more ;-)
This /proc stuff seems to work perfectly on Linux, however I can't get it to work on OS/X, and I think from memory it doesn't work under OpenBSD also.
Indeed. The /proc thing works very well under Linux. I've uncovered a few descriptor leaks using that method in some of the extra stuff we have in our code. You need to be especially mindful of those when using copyover since it carries over leaked ones along with your active ones. Needless to say if you leak enough of them this will cause you a world of hurt. Plugging them can be somewhat of a pain too. :)
The best thing to do when you're having an abundance of descriptor leaks, is to just start with the first file you have, search for an instance of 'fopen' and verify that whatever was opened, gets closed again. Continue doing this until you've gone through all of your files that have and fopen's in them. Sounds painful, but the alternative if you don't bring the situation under control can be much worst.
Was talking about open sockets actually. Not file handles. And I've at least traced down that they're coming out of the webserver module. Which I suppose was to be expected since the descriptor handling isn't the best in there. At least I've stopped it from bleeding past a copyover. :)
Another question I think fits in here. Whats up with copyover for SWR. It lags the login screen so you don't even see the intro screen. Any ideas on why it does that?
Thanks.
You confuse me a bit. Every version of copyover I've seen has had nothing to do with a login or intro. It's merely a save of who's connected and where they are located (and in the case of Samson's hotboot code, object and mobile positions too). So that when the copyover is complete, everything is put back were it was and the player experiences nothing more then what seems like a brief moment of bad lag. If you took out all of the messages too the player, most wouldn't likely even know a reboot occured.
What I meant was that after I reboot and try to login with a differen't name the "help greeting" file doesn't even show up. It just says connected, its like horrible login lag. I hope that helps because its a weird problem. Anyways, thanks for the help.
Not sure why SWR would bomb that way on a copyover, but it sounds like there's definitely some kind of problem. Not having worked with it before, I can't say for sure what the cause is. Which version of SWR? Perhaps if I get bored I'll look at it. Also, which version of copyover? :)
Describe what happens during a copyover and right after, as well as what happens when you try to log on. By the way I understand it, the copyover works right, but when you or anyone else attmpts to log on to your mud after a copyover the 'greeting' screen is no displayed. Am I correct in this? If that's the case I have at least a partial idea what may be causing it.
Sorry, forgot to check the forum for replies for a few days. Anyways, yes, that is the exact problem, it works fine but the 'Greeting' help file does not show up when you try to log on. It just says you are connected. And to answer your question Samson, its the copyover snippet from Kyndig. Its under snippets. Here is the URL:
http://www.kyndig.com/codes/diku/merc/smaug/Star_Wars
Anyways, sorry for the delay. Thanks for all the help.
Two questions. What client do you use? and Even though the greeting doesn't display, can you still log on by typing your name and such? Also, open up comm.c and in:
void new_descriptor()
look for this chunk of code:
/*
* Send the greeting.
*/
{
extern char * help_greeting;
if ( help_greeting[0] == '.' )
write_to_buffer( dnew, help_greeting+1, 0 );
else
write_to_buffer( dnew, help_greeting , 0 );
}
If you can still log on and that code is not there, see if you can locate something similar to it. But, if by chance you can't even log on properly, you have a much worst situation (you may have skipped a part in the snippet).
I used Gmud(to answer your first question) and I have no clue if you can log on. It just says connected, but its so laggy that the greeting doesn't pop up, so I can't even test if you can log on. I've got that you posted code in comm.c. I've checked my code 4 times to be sure I did everything in the snippet and I'm positive I did. Anyways, I think its just laggy, so I guess my question is do you have any ideas on how I could reduce that lag, or should I just not use that code?
Thanks again for the help.
I'm still a bit confused on your problems. You said that everyone who's already connected is still ok right? If that were the case the wouldn't they be 'laggy' too? How do you know if you can't log on if you've never tried? Just because the greeting doesn't show up, doesn't mean you necessarily can't log on. If it doesn't kick you off right away after saying 'connected' it's likely waiting for your username. try it.
Alright, let me try and explain this as best I can.
Yes, everyone who is on is still okay, and not lagged down or anything, so I guess lag is not the cause. That was just my initial thought. And to test it I left my Gmud up all night until I checked it the next day (about 14 hours later) and it still just said connected, the greeting hadn't popped up. If I try and put in anything, like a user name or password, it does nothing, it is just entered like in Gmud, but it does nothing. So yeah, I hope that helpped explain the problem a bit better.
Personally I wouldn't wait 14 hours for the greeting. :P
Sounds like - if it is connected - the server has got confused and is looking for input on the wrong descriptor.
I just left it on over night, so I didn't really have to wait 14 hours. Anyways, do you have any ideas on how I could fix it?
Thanks.
To help fix it we would have to reproduce it. What version of SWR exactly do you have? The URL of it, that is. You gave the location of the copyover code. What operating system are you using? Cygwin? If so on what platform exactly. Or something else?
The SWR I'm using is the one from kyndig:
kyndig.com/codes/diku/merc/smaug/Star_Wars
I'm running it out of my shell acount which is Unix I beleive.
Did I tell you enough information or are you all out of ideas. I really don't know whats wrong with it but its rather disturbing not being able to copyover even though the code is in. Anyways, if you guys don't have a clue on how I can fix this than thats alright. Thanks for the help.
I don't want to seem unhelpful, but couldn't you ask at the Kyndig site about this? You have the SMAUG SWR version from there, and the copyover snippet from there, and it doesn't work, so why not ask at the site in question?
You don't seem too sure what operating system you are running on, you said "Unix I believe". Aren't you sure? Which Unix? Linux? OpenBSD? FreeBSD? NetBSD? Solaris? Which version of the operating system?
To have much hope of debugging someone would have to download the SWR source, add the snippet, compile it, test it, reproduce the problem, if they could, and then work out why it is happening. It mightn't even happen if you are on, say Red Hat Linux 6, and they are testing on Debian version x.
I have seen this problem many times and though I don't know how to fix it I might be able to give you some insight on what the problem does. Exactly what it does is connect you, and then it is like *not is* you were just hit by a lag spell except that it lasts until the mud is rebooted. I was a long time player of Gundam Wing Mud *when it was actually up* and this mud had this problem a few times.
Anyways, they would announce to their players that a copyover was coming and save everyone and copyover. Well, more than once the copyover brought a good portion of lag so I would get off and try and reconnect. You would connect, and it doesn't matter what computer or OS you are running *I tried it on a few different comps with different OS*, but you would be stuck in limbo *limbo being connected without the ability to do anything. The greeting wouldn't pop up, you couldn't log in and all you could do is either get off and try again later and hope they rebooted or sit there and wait. It doesn't go away until you rebooted.
I don't know if this has to do with the OS the mud is using or some code that doesn't direct your connection to the right place but it is pretty easy to see it happen. I'm sure that wightknight would be able to show you its affects if you really wanted to see them happen, shrug he might not but I think he would show you for the sake of finding the problem.
I hope this helped you understand the problem a little better if you didn't understand it before. Good luck on figuring it out.
So I'm guessing no one has any insights to my problems? Vicious stated the problems exactly, anyways, if you guys don't know how to fix it or any ideas then thats okay.
Thanks for all the help so far...
Hello all. Im new to this thread and felt that it would be appropriate to post this here. I have recently added in copyover to a godwars deluxe codebase. Im having the same issue has described. When i ./startup & in the shell the mud starts fine and you can connect, login, and play. Once you copyover, you can still play if you are already connected. If you disconnect and try to reconnect while the mud is running off the copyover, it will not display the greeting nor let you login. It only displays the messaged connected to: IPADDRESS and sits there. I was wondering if there is any information on how to fix this yet. Im sure i just have missed something in adding in the copyover snippet. My theory is that it just wont open new descriptors for players who try to connect after the copyover has been initiated. How to fix this im am not certain just yet.
Thanks in advance,
Jaden
I don't know the copyover snippet, but from what you describe it sounds like the "listener" is not working.
To accept new connections there is a special socket that listens for them, and when it gets one it creates a new socket (for the new player). I would be checking around the code for the listening port.
Well, I did eventually fix it. It was my fault. In SWR/SMAUG it has multiple ports that the game runs on. Back then I had just commented them out, and forgetting I didnt us them, I went a head and installed the whole copyover snippet, which assumed I was using them. Basically, it ties the listening port, however, it does not acknowledge connections. If its anything like swr, go to a line like this:
execl (EXE_FILE, "swreality", buf, "copyover", buf2, buf3, buf4, buf5, (char *) NULL);
And make sure everything is correct.
In smaug/swr the clue's are in the preceeding lines, which are
sprintf (buf, "%d", port);
sprintf (buf2, "%d", control);
sprintf (buf3, "%d", control2);
sprintf (buf4, "%d", conclient);
sprintf (buf5, "%d", conjava);
In this case, merely comment out the ones you are not using, or remove them completely. Both solutions work seem to work correctly. However, I am not experienced with the GodWars base, so I have no clue if it is even remotely similar.
If you still can't figure it out, just post the function with the call to execl.