ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have an executable in Linux (I'm using FC5) that I need to run as a service, and eventually can be controlled by utilities such as webmin. How do I do this exactly?
Also, I want to dump out log messages to a log file (flat text). However, I would like to set a limit for the log file so the size doesn't grow too big. How do I make it so the log message only shows say the last 5000 activities logged? It is also necessary to minimize the amount of processing used for the logging activities so it doesn't take up too much cpu cycle on the server.
Another thing is that in the event the server crashed, I would like to track as accurately possible as the events right before it happened. Is there someway I could force the event messages to be commited to the log file immediately? Is fprintf() sufficient to use for this case?
As far as your limiting the amount of data in your file - use a rolling log file. That is when it reaches the limit, it starts over again.
fprintf is definitely not sufficient to flush it immediately. Depending upon you file system options (Is your file system mounted as synchronized - I doubt it) you may have to do a combination of:
fflush to flush the io buffer
fsync to sync the file
sync to force changes to the file system. I think with an ext3 file system for example you have to do a sync since changes only get commited every 5 seconds by default but I believe a sync will force this immediately.
I have used a logging tool in embedded Linux systems called log4cxx which is part of the apache project. Take a look at it for good ideas when it comes to logging. You can redirect logging output to telnet sessions, rolling log files (with a certain number of backup files) and/or the console.
Hi do you have an example to show the correct usage of fflush and fsync? I will try this out but just need something for reference. Thanks,
Quote:
Originally Posted by Denes
...
fflush to flush the io buffer
fsync to sync the file
sync to force changes to the file system. I think with an ext3 file system for example you have to do a sync since changes only get commited every 5 seconds by default but I believe a sync will force this immediately.
I have used a logging tool in embedded Linux systems called log4cxx which is part of the apache project. Take a look at it for good ideas when it comes to logging. You can redirect logging output to telnet sessions, rolling log files (with a certain number of backup files) and/or the console.
Even flushing data will not comit it to the drive because the kernel has the last say. An exaple is laptop mode where you can increase the amount of time via the kernel.
Then again I do vagly remeber seeing something that did just dont know how they did it.
// Write to file
fprintf(file, "Blah Blah");
// Flush io
fflush(file);
// Flush file
fsync(file);
// Force write to media
service("sync");
Those are all the flush functions I know about and you may be able to get rid of one or two of them since they may be redundant. In my experience not everything was flushed until after sync was called.
Look at section 8.4 fsync and fdatasync: Flushing Disk Buffers in "Advanced Linux Programming", that section has a small example.
You can find a free copy of that somewhere on the web.
For the log rotation part, don't write this in your code. Just let the sysadmin run logrotate on the file if they really want to.
On the OS caching effects, the most straightfoward way to approach it is to open() the file and pass O_DIRECT as an option. Then fdopen() the file descriptor you get back if you want to turn it into a FILE *.
thanks but how do I make it so I can control from webmin? (start/stop service)?
To be honest, I've never used webmin. So for me the question is what one can do with it.
I would attempt the following:
1)
Modify your program so it can handle a signal (i.e. <ctrl>C) and stops nicely on that (flush buffers, close files etc).
2)
Write a script that can handle the arguments 'start' and 'stop'. When you issue scriptname start, it will start the application (as described before), if you issue scriptname stop, the script will issue a killall command to stop the application.
OR
Write to scripts, one for start and one for stop
3)
Tell webmin to use that script or scripts (that's the part that I don't know).
PS You can have a look at an existing service that is running on your machine (mysql, apache, ......) and check what webmin does.
This is how my slackware box starts and stops mysql
Code:
# Start mysqld:
mysqld_start() {
if [ -x /usr/bin/mysqld_safe ]; then
# If there is an old PID file (no mysqld running), clean it up:
if [ -r /var/run/mysql/mysql.pid ]; then
if ! ps axc | grep mysqld 1> /dev/null 2> /dev/null ; then
echo "Cleaning up old /var/run/mysql/mysql.pid."
rm -f /var/run/mysql/mysql.pid
fi
fi
/usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/run/mysql/mysql.pid $SKIP &
fi
}
# Stop mysqld:
mysqld_stop() {
# If there is no PID file, ignore this request...
if [ -r /var/run/mysql/mysql.pid ]; then
killall mysqld
# Wait at least one minute for it to exit, as we don't know how big the DB is...
for second in 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 \
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 60 ; do
if [ ! -r /var/run/mysql/mysql.pid ]; then
break;
fi
sleep 1
done
if [ "$second" = "60" ]; then
echo "WARNING: Gave up waiting for mysqld to exit!"
sleep 15
fi
fi
}
# Restart mysqld:
mysqld_restart() {
mysqld_stop
mysqld_start
}
# process script argument
case "$1" in
'start')
mysqld_start
;;
'stop')
mysqld_stop
;;
'restart')
mysqld_restart
;;
*)
echo "usage $0 start|stop|restart"
esac
PS you can specify a signal with the killall command. The default is SIGTERM, so instead of modifying your code to handle <ctrl>C (I think that that is SIGQUIT), you can write it to handle SIGTERM.
Does anyone know if you use O_DIRECT with the file does this make sure the data gets flushed to the media immediately on a write even with filesystems not mounted synchronously? For example ext3 that only gets committed every 5 seconds by default. Or do you have to use an explicit sync to get it to commit? I am just wondering what steps to flushing file data does O_DIRECT take automatically. I would think it would make it so that you would not have to call fflush and fsync but I am not sure about the sync call.
// Write to file
fprintf(file, "Blah Blah");
// Flush io
fflush(file);
// Flush file
fsync(file);
// Force write to media
[s]service("sync");[/s]
system("sync"); Is this what you meant?
Those are all the flush functions I know about and you may be able to get rid of one or two of them since they may be redundant. In my experience not everything was flushed until after sync was called.
Look at section 8.4 fsync and fdatasync: Flushing Disk Buffers in "Advanced Linux Programming", that section has a small example.
You can find a free copy of that somewhere on the web.
By the way, a little offtopic, but system("sync"); is not only bad programming, but a security risk. If your program needs to sync data to the filesystem and guarantee, it should call sync();
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.