1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte * CDDL HEADER START
3*fcf3ce44SJohn Forte *
4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte *
8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte * and limitations under the License.
12*fcf3ce44SJohn Forte *
13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte *
19*fcf3ce44SJohn Forte * CDDL HEADER END
20*fcf3ce44SJohn Forte */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23*fcf3ce44SJohn Forte * Use is subject to license terms.
24*fcf3ce44SJohn Forte */
25*fcf3ce44SJohn Forte
26*fcf3ce44SJohn Forte #include <signal.h>
27*fcf3ce44SJohn Forte #include <sys/types.h>
28*fcf3ce44SJohn Forte #include <sys/time.h>
29*fcf3ce44SJohn Forte #include <sys/stat.h>
30*fcf3ce44SJohn Forte #include <fcntl.h>
31*fcf3ce44SJohn Forte #include <stdio.h>
32*fcf3ce44SJohn Forte #include <unistd.h>
33*fcf3ce44SJohn Forte #include <strings.h>
34*fcf3ce44SJohn Forte #include <errno.h>
35*fcf3ce44SJohn Forte #include <assert.h>
36*fcf3ce44SJohn Forte
37*fcf3ce44SJohn Forte #include "cfg_impl.h"
38*fcf3ce44SJohn Forte #include "cfg_lockd.h"
39*fcf3ce44SJohn Forte
40*fcf3ce44SJohn Forte
41*fcf3ce44SJohn Forte #define segment_off(s) ((off_t)(s) * sizeof (pid_t))
42*fcf3ce44SJohn Forte
43*fcf3ce44SJohn Forte static int local_lockfd;
44*fcf3ce44SJohn Forte static int local_lockfda;
45*fcf3ce44SJohn Forte
46*fcf3ce44SJohn Forte void
cfg_lfinit()47*fcf3ce44SJohn Forte cfg_lfinit()
48*fcf3ce44SJohn Forte {
49*fcf3ce44SJohn Forte local_lockfd = open(CFG_RDEV_LOCKFILE, O_RDWR|O_CREAT, 0644);
50*fcf3ce44SJohn Forte local_lockfda = open(CFG_RDEV_LOCKFILE, O_RDWR|O_APPEND, 0644);
51*fcf3ce44SJohn Forte }
52*fcf3ce44SJohn Forte
53*fcf3ce44SJohn Forte int
cfg_filelock(int segment,int flag)54*fcf3ce44SJohn Forte cfg_filelock(int segment, int flag)
55*fcf3ce44SJohn Forte {
56*fcf3ce44SJohn Forte struct flock lk;
57*fcf3ce44SJohn Forte struct stat sb;
58*fcf3ce44SJohn Forte pid_t pid = 0;
59*fcf3ce44SJohn Forte off_t off = segment_off(segment);
60*fcf3ce44SJohn Forte int rc;
61*fcf3ce44SJohn Forte
62*fcf3ce44SJohn Forte while (fstat(local_lockfd, &sb) == -1 && errno == EINTR)
63*fcf3ce44SJohn Forte ;
64*fcf3ce44SJohn Forte if (sb.st_size < off + sizeof (pid_t)) {
65*fcf3ce44SJohn Forte if ((flag&O_CREAT) == 0)
66*fcf3ce44SJohn Forte return (CFG_LF_EOF);
67*fcf3ce44SJohn Forte write(local_lockfda, &pid, sizeof (pid_t));
68*fcf3ce44SJohn Forte }
69*fcf3ce44SJohn Forte bzero(&lk, sizeof (lk));
70*fcf3ce44SJohn Forte lk.l_type = F_WRLCK;
71*fcf3ce44SJohn Forte lk.l_whence = SEEK_SET;
72*fcf3ce44SJohn Forte lk.l_start = off;
73*fcf3ce44SJohn Forte lk.l_len = (off_t)sizeof (pid_t);
74*fcf3ce44SJohn Forte
75*fcf3ce44SJohn Forte while ((rc = fcntl(local_lockfd, F_SETLK, &lk)) < 0 && errno == EINTR)
76*fcf3ce44SJohn Forte ;
77*fcf3ce44SJohn Forte if (rc == -1 && errno == EAGAIN)
78*fcf3ce44SJohn Forte return (CFG_LF_AGAIN);
79*fcf3ce44SJohn Forte
80*fcf3ce44SJohn Forte return (CFG_LF_OKAY);
81*fcf3ce44SJohn Forte }
82*fcf3ce44SJohn Forte
83*fcf3ce44SJohn Forte
84*fcf3ce44SJohn Forte int
cfg_fileunlock(int segment)85*fcf3ce44SJohn Forte cfg_fileunlock(int segment)
86*fcf3ce44SJohn Forte {
87*fcf3ce44SJohn Forte struct flock lk;
88*fcf3ce44SJohn Forte off_t off = segment_off(segment);
89*fcf3ce44SJohn Forte
90*fcf3ce44SJohn Forte bzero(&lk, sizeof (lk));
91*fcf3ce44SJohn Forte lk.l_type = F_UNLCK;
92*fcf3ce44SJohn Forte lk.l_whence = SEEK_SET;
93*fcf3ce44SJohn Forte lk.l_start = off;
94*fcf3ce44SJohn Forte lk.l_len = (off_t)sizeof (pid_t);
95*fcf3ce44SJohn Forte
96*fcf3ce44SJohn Forte while (fcntl(local_lockfd, F_SETLK, &lk) < 0 && errno == EINTR)
97*fcf3ce44SJohn Forte ;
98*fcf3ce44SJohn Forte return (1);
99*fcf3ce44SJohn Forte }
100*fcf3ce44SJohn Forte
101*fcf3ce44SJohn Forte void
cfg_readpid(int segment,pid_t * pidp)102*fcf3ce44SJohn Forte cfg_readpid(int segment, pid_t *pidp)
103*fcf3ce44SJohn Forte {
104*fcf3ce44SJohn Forte off_t off = segment_off(segment);
105*fcf3ce44SJohn Forte lseek(local_lockfd, off, SEEK_SET);
106*fcf3ce44SJohn Forte read(local_lockfd, pidp, sizeof (pid_t));
107*fcf3ce44SJohn Forte }
108*fcf3ce44SJohn Forte
109*fcf3ce44SJohn Forte void
cfg_writepid(int segment,pid_t pid)110*fcf3ce44SJohn Forte cfg_writepid(int segment, pid_t pid)
111*fcf3ce44SJohn Forte {
112*fcf3ce44SJohn Forte off_t off = segment_off(segment);
113*fcf3ce44SJohn Forte lseek(local_lockfd, off, SEEK_SET);
114*fcf3ce44SJohn Forte write(local_lockfd, &pid, sizeof (pid_t));
115*fcf3ce44SJohn Forte }
116*fcf3ce44SJohn Forte
117*fcf3ce44SJohn Forte void
cfg_enterpid()118*fcf3ce44SJohn Forte cfg_enterpid()
119*fcf3ce44SJohn Forte {
120*fcf3ce44SJohn Forte int i;
121*fcf3ce44SJohn Forte pid_t pid;
122*fcf3ce44SJohn Forte
123*fcf3ce44SJohn Forte for (i = 0; ; i++) {
124*fcf3ce44SJohn Forte if (cfg_filelock(i, O_CREAT) == CFG_LF_OKAY) {
125*fcf3ce44SJohn Forte cfg_readpid(i, &pid);
126*fcf3ce44SJohn Forte if (pid != (pid_t)0) {
127*fcf3ce44SJohn Forte cfg_fileunlock(i);
128*fcf3ce44SJohn Forte continue;
129*fcf3ce44SJohn Forte }
130*fcf3ce44SJohn Forte pid = getpid();
131*fcf3ce44SJohn Forte cfg_writepid(i, pid);
132*fcf3ce44SJohn Forte break;
133*fcf3ce44SJohn Forte }
134*fcf3ce44SJohn Forte }
135*fcf3ce44SJohn Forte }
136