fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <signal.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/time.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stat.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <fcntl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <unistd.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <strings.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <assert.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "cfg_impl.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "cfg_lockd.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define segment_off(s) ((off_t)(s) * sizeof (pid_t))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int local_lockfd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int local_lockfda;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecfg_lfinit()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte local_lockfd = open(CFG_RDEV_LOCKFILE, O_RDWR|O_CREAT, 0644);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte local_lockfda = open(CFG_RDEV_LOCKFILE, O_RDWR|O_APPEND, 0644);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecfg_filelock(int segment, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct flock lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct stat sb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pid_t pid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off_t off = segment_off(segment);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fstat(local_lockfd, &sb) == -1 && errno == EINTR)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sb.st_size < off + sizeof (pid_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((flag&O_CREAT) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (CFG_LF_EOF);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte write(local_lockfda, &pid, sizeof (pid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&lk, sizeof (lk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_type = F_WRLCK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_whence = SEEK_SET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_start = off;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_len = (off_t)sizeof (pid_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((rc = fcntl(local_lockfd, F_SETLK, &lk)) < 0 && errno == EINTR)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == -1 && errno == EAGAIN)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (CFG_LF_AGAIN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (CFG_LF_OKAY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecfg_fileunlock(int segment)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct flock lk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off_t off = segment_off(segment);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&lk, sizeof (lk));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_type = F_UNLCK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_whence = SEEK_SET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_start = off;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lk.l_len = (off_t)sizeof (pid_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (fcntl(local_lockfd, F_SETLK, &lk) < 0 && errno == EINTR)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecfg_readpid(int segment, pid_t *pidp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off_t off = segment_off(segment);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lseek(local_lockfd, off, SEEK_SET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte read(local_lockfd, pidp, sizeof (pid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecfg_writepid(int segment, pid_t pid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte off_t off = segment_off(segment);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lseek(local_lockfd, off, SEEK_SET);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte write(local_lockfd, &pid, sizeof (pid_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecfg_enterpid()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pid_t pid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; ; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cfg_filelock(i, O_CREAT) == CFG_LF_OKAY) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfg_readpid(i, &pid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pid != (pid_t)0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfg_fileunlock(i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pid = getpid();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cfg_writepid(i, pid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}