1822004 Members
3957 Online
109639 Solutions
New Discussion юеВ

File locking in HPUX

 
SOLVED
Go to solution
Manish_33
Advisor

File locking in HPUX

Hi,

I am trying have a write lock on the same binary which I am running. My sample program runs fine on Solaris but fails on AIX and HPUX with error message "Text file busy". Also I noticed on AIX that if I take a lock on any other executable I am not able to execute it while the lock is held. Could someone suggest if this is a standard POSIX behaviour ??

Below is my sample program

############################################################
#include
#include
#include
#include
#include
#define FILENAME "/home/cics/katiyar/a.out"

int main(int argc, char *argv[])
{
/* l_type l_whence l_start l_len l_pid */
struct flock fl = { F_WRLCK, SEEK_SET, 0, 0, 0 };
int fd;

fl.l_pid = getpid();

if (argc > 1)
fl.l_type = F_RDLCK;

if ((fd = open(FILENAME, O_WRONLY|O_NONBLOCK|O_CREAT|O_EXCL)) == -1) {
if(errno != EEXIST ){
perror("open");
exit(1);
}
else{
if ((fd = open(FILENAME, O_WRONLY|O_NONBLOCK)) == -1) {
perror("open here");
exit(1);
}
}
}
chmod(FILENAME,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

printf("Press to try to get lock: ");
getchar();
printf("Trying to get lock...");

if (fcntl(fd, F_SETLK, &fl) == -1) {
perror("fcntl");
printf("errno = %d\n",errno);
exit(1);
}

printf("got lock\n");
printf("Press to release lock: ");
getchar();

fl.l_type = F_UNLCK; /* set to unlock same region */

if (fcntl(fd, F_SETLK, &fl) == -1) {
perror("fcntl");
exit(1);
}

printf("Unlocked.\n");

close(fd);
}

############################################################
8 REPLIES 8
Matti_Kurkela
Honored Contributor
Solution

Re: File locking in HPUX

I don't know about POSIX compliance, but I think this is related to virtual memory management.

When you page out program code, it's inefficient to actually write the code to swap, because you already have the program code on disk. You can optimize by just discarding the pages and reading them back from the original binary file if/when needed.

If this optimization is done, it would be a good idea to make the VM subsystem hold a lock on the binary to disallow any changes to it.

If a program's binary could be modified while it's executing, after some page-ins the program code in memory would be corrupted: some of the code would be from the original version and some from the modified version. This would probably make the program crash sooner or later.

In AIX, the "vice-versa" situation is apparently taken into account too: if someone is holding a write lock on a binary, it might not be a good idea to execute it, as the holder of the lock might be modifying the binary.

MK
MK
Dennis Handly
Acclaimed Contributor

Re: File locking in HPUX

Why are you trying to lock the executable? You should not be fiddling with these. What are you really trying to do??

You should instead lock some data file.
You didn't mention but I assume you got ETXTBSY when you opened the file.
Manish_33
Advisor

Re: File locking in HPUX

Hi Dennis,

We have a reqmnt where there should not be two instances of a daemon. Since we bind our daemon to dynamic port, it allows starting two instances. Normally what daemons do is that they keep their pid in a file and the other process checks if that pid is available. but since pids can be reused this is not full proof. So we thought of having a temp file on which we take a write lock and when other process starts it also tries and fails. This had a problem that a user can delete the temp file. So we thought of having the lock on the daemon itself. So that our issue is resolved.

but this method works on Solaris, but fails on HPUX and AIX.

Hope i am clear. Is there any other full proof method that anyone can suggest ?

Dennis Handly
Acclaimed Contributor

Re: File locking in HPUX

>Is there any other foolproof method that anyone can suggest?

Well the demon can use ps to look to see if it already running. Or you can put the tempfile in a directory with a sticky bit so nobody but the owner or root can remove the file.

Or you can create a very small shared memory area. And if it exists, you don't start. Of course if you abort, some admin would have to clean up that file or memory area. Of course with that PID file, you could just see if that PID was there. Or check farther and see if that PID is running your demon:
$ UNIX95= ps -C demon-name -opid= | grep -w -f pid-file
Manish_33
Advisor

Re: File locking in HPUX

Hi Dennis,

yes each of these methods are correct, but as you see each of them fails in some particular conditions....specially in case of aborts you cannot be sure and some manual intervention is needed. Also we don't run as root but still want to have full control that is why we chose this method.

As you can see , if this works we will not have any issues. Also since our application is large multi-threaded and creates lots of shared memories, we don't want to introduce any more.

Thanks a lot
Dennis Handly
Acclaimed Contributor

Re: File locking in HPUX

>specially in case of aborts you cannot be sure and some manual intervention is needed.

The PID file doesn't have this problem. (With checking with ps(1).)

>Also since our application is large multi-threaded and creates lots of shared memories, we don't want to introduce any more.

If you have named the shared memory, just use an existing name.
Emil Velez
Honored Contributor

Re: File locking in HPUX


I would allocate a named semiphore in memory and when the program starts it locks the semiphore and if another program starts it exits since the semiphore is locked.

Here is a example of semlock which was from the linux programmers guide but works on HPUX

This example does a block and makes the program wait if the semiphore is locked. Change the code to make it just exit if the semiphore is locked.
A. Clay Stephenson
Acclaimed Contributor

Re: File locking in HPUX

Fundamentally, it really doesn't matter whether you use a pid file (with or without locks), a semaphore, a shared memory segment, or IPC messages because the issue is exactly the same. If the flag exists, the daemon doesn't start, it issues an error message, and above all it leaves the lock (whatever it is unchanged). Only when the daemon exits normally (generally as a result of receiving a signal but sometimes as a specific client request) is the lock mechanism removed. In the interest of finding a solution that works everywhere, I would tend to use the time-honored method of a pid file --- for your purposes the pid can be considered unique because pids are only recycled when they are not in use. The other nice feature of a pid file is that it allows a very easy method for the same command to examine the its status or to terminate or reconfigure itself without knowing the pid of the daemon directly --- just like inetd -c works.

Of course, all this assumes that you don't use kill -9 --- which you should be doing anyway.
If it ain't broke, I can fix that.