Does anyone know how to lock files that have got spurious locks on
them?  I discovered that a reboot will do it.  :-(

At home on my venerable RH4.2 system, I'm finding recently that mail
spooled to be sent is being locked, and gets stuck.

When mail is sent and I'm not connected, it gets spooled in
/var/spool/mqueue.  I'm using sendmail for mail delivery. (*)

At regular intervals, sendmail is run via cron to flush mail out (in
case the mail is being sent locally, you see).  Since I made that
change, the problem started occurring.

What I've found is that the control files starting with "q" in /var/spool/mqueue
are locked (with flock, I think).  The inodes corresponding to the
locked files appear in the list of locked files if you cat /proc/locks,
but I can find no information on whether it's possible to use
/proc/locks to selectively remove locks.  Likewise, I wrote a program
to unlock files via flock().  flock() appears to succeed, but it
doesn't unlock the file!

I also added a re-try using fcntl to set F_UNLCK in the struct flock,
and that failed with an EBUSY (the man page does not list that as a
valid error - it should return EAGAIN if the file is locked). That may
be spurious - it probably wasn't locked with fcntl().

I suddenly wonder - I was running the unlock program as root;  I think
the /var/spool/mqueue files were also root owned, so that would have
been right, wouldn't it?  Was file locking and unlocking buggy in RH4.2
(kernl 2.0.32 actually)?

luke

(*) I believe qmail sends a separate copy of an outgoing mail to each
    recipient.  Not practical for those occasions when my wife has to
    send her 1Mb CV in Word to umpteen agents.

    I *plan* to change over to postfix at some stage.

---- unlock.c ----
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

int
unlock(char *fname)
{
    int                 fd;
    struct flock        lock;

    if ((fd = open(fname, O_RDONLY|O_NONBLOCK)) == -1)
    {
        perror(fname);
        return 1;
    }
    if (flock(fd, LOCK_UN) == -1)
    {
        perror(fname);
        close(fd);
        return 2;
    }
    close(fd); /* Paranoia sets in. */
    if ((fd = open(fname, O_RDONLY|O_NONBLOCK)) == -1)
    {
        perror(fname);
        return 1;
    }
    memset(&lock, 0, sizeof lock);
    lock.l_type = F_UNLCK;
    if (fcntl(fd, F_SETLK, &lock) == -1)
    {
        perror(fname);
        close(fd);
        return 8;
    }

    close(fd);
    return 0;
}

int
main(int argc, char **argv)
{
    int         i;
    int         status = 0;

    for (i = 1; i < argc; ++i)
    {
        status |= unlock(argv[i]);
    }
    return status;
}






--
SLUG - Sydney Linux Users Group Mailing List - http://www.slug.org.au
To unsubscribe send email to [EMAIL PROTECTED] with
unsubscribe in the text

Reply via email to