xref: /titanic_52/usr/src/lib/libdscfg/common/cfg_lockdlck.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
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
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
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
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
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
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
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