4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <netinet/tcp.h>
39 #include "cfg_lockd.h"
41 static daemonaddr_t clientaddr
;
42 static daemonaddr_t server
;
44 static unsigned short server_port
= CFG_SERVER_PORT
;
45 static int lock_soc
= 0;
46 static int pf_inet
= AF_INET
;
49 static int initresult
;
50 static pid_t socket_pid
;
52 static void cfg_lockd_reinit();
54 static int last_cmd
= -1;
55 static uint8_t seq
= 0;
60 struct lock_msg message_buf
;
63 if (last_cmd
== cmd
) {
64 message_buf
.seq
= seq
;
66 message_buf
.seq
= ++seq
;
69 message_buf
.message
= cmd
;
70 if ((message_buf
.pid
= getpid()) != socket_pid
)
74 rc
= sendto(lock_soc
, &message_buf
, sizeof (message_buf
), 0,
75 (struct sockaddr
*)&server
, sizeof (server
));
76 } while (rc
== -1 && errno
== EINTR
);
77 #ifdef CFG_LOCKD_DEBUG
85 read_msg(struct lock_msg
*mp
)
90 /* wait for response */
98 rc
= poll(&fds
, 1, 500);
100 #ifdef CFG_LOCKD_DEBUG
101 fprintf(stderr
, "LOCKD: resending last command (%d)\n",
107 (rc
== -1 && errno
== EINTR
));
111 rc
= recvfrom(lock_soc
, mp
, sizeof (*mp
), 0,
113 } while (rc
== -1 && errno
== EINTR
);
114 #ifdef CFG_LOCKD_DEBUG
124 struct lock_msg message_buf
;
127 read_msg(&message_buf
);
128 } while (message_buf
.seq
!= seq
|| message_buf
.message
!= LOCK_LOCKED
);
134 struct lock_msg message_buf
;
137 read_msg(&message_buf
);
138 } while (message_buf
.seq
!= seq
|| message_buf
.message
!= LOCK_ACK
);
144 #ifdef CFG_LOCKD_DEBUG
152 #ifdef CFG_LOCKD_DEBUG
153 fp
= fopen("/tmp/locktag", "a");
156 fprintf(fp
, "%19.19s read lock acquired\n", ctime(&t
));
166 #ifdef CFG_LOCKD_DEBUG
170 send_cmd(LOCK_WRITE
);
174 #ifdef CFG_LOCKD_DEBUG
175 fp
= fopen("/tmp/locktag", "a");
178 fprintf(fp
, "%19.19s write lock acquired\n", ctime(&t
));
188 #ifdef CFG_LOCKD_DEBUG
192 send_cmd(LOCK_NOTLOCKED
);
196 #ifdef CFG_LOCKD_DEBUG
197 fp
= fopen("/tmp/locktag", "a");
200 fprintf(fp
, "%19.19s ----- lock released\n", ctime(&t
));
214 cfg_lockedby(pid_t
*pidp
)
216 struct lock_msg message_buf
;
217 send_cmd(LOCK_LOCKEDBY
);
218 read_msg(&message_buf
);
219 *pidp
= message_buf
.pid
;
220 return ((cfglockd_t
)message_buf
.message
);
233 if ((lock_soc
= socket(pf_inet
, SOCK_DGRAM
, 0)) < 0) {
234 #ifdef CFG_LOCKD_DEBUG
235 fprintf(stderr
, "libcfg: failed to create socket\n");
240 clientaddr
.sin_family
= AF_INET
;
241 clientaddr
.sin_addr
.s_addr
= INADDR_ANY
;
242 clientaddr
.sin_port
= htons(0);
243 if (bind(lock_soc
, (struct sockaddr
*)&clientaddr
,
244 sizeof (clientaddr
)) < 0) {
245 #ifdef CFG_LOCKD_DEBUG
250 socket_pid
= getpid();
255 * Re-initialise after a fork has been detected.
257 * Needs to create a new socket for new process to receive messages
258 * from the lock daemon and enter pid into lock file so that the daemon
259 * can detect new processes exit if it doesn't call unlock first.
268 if (cfg_lockd_socket()) {
281 int pid
= 0x12345678;
284 /* only perform reinit if init worked first time */
285 if (getpid() != socket_pid
&& initresult
!= 0)
293 /* check if there's a lock daemon out there */
294 if ((fp
= fopen(CFG_PIDFILE
, "r")) == NULL
)
296 if (fscanf(fp
, "%d\n", &pid
) != 1) {
301 if (kill((pid_t
)pid
, 0) != 0)
304 /* there is a lock daemon */
307 if (cfg_lockd_socket())
310 if ((hp
= gethostbyname("localhost")) == NULL
) {
311 #ifdef CFG_LOCKD_DEBUG
312 fprintf(stderr
, "Can't find hostent for %s\n", "localhost");
316 (void) memcpy(&(server
.sin_addr
.s_addr
), *(hp
->h_addr_list
),
317 sizeof (server
.sin_addr
));
318 server
.sin_port
= htons(server_port
);
319 server
.sin_family
= hp
->h_addrtype
;