Mercurial > illumos > illumos-gate
changeset 12824:3e6822aec2be
6963894 rpc.mdcommd should use file locking semantics to protect the MCT
author | James Hall <james.hall@oracle.com> |
---|---|
date | Tue, 13 Jul 2010 11:35:50 +0100 |
parents | dec8caad2567 |
children | bc605e2f6f81 |
files | usr/src/cmd/lvm/rpc.mdcommd/mdmn_commd_server.c |
diffstat | 1 files changed, 49 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/lvm/rpc.mdcommd/mdmn_commd_server.c Tue Jul 13 18:17:30 2010 +0530 +++ b/usr/src/cmd/lvm/rpc.mdcommd/mdmn_commd_server.c Tue Jul 13 11:35:50 2010 +0100 @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <unistd.h> @@ -786,6 +785,7 @@ size_t filesize; caddr_t addr; char table_name[32]; + struct flock fl; filesize = (sizeof (md_mn_mct_t)); (void) snprintf(table_name, sizeof (table_name), "%s%d", @@ -803,6 +803,53 @@ return (-1); } /* + * Ensure that we are the only process that has this file + * mapped. If another instance of rpc.mdcommd has beaten us + * then we display the failing process and attempt to terminate + * it. The next call of this routine should establish us as + * the only rpc.mdcommd on the system. + */ + (void) memset(&fl, 0, sizeof (fl)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = filesize + 1; + + if (fcntl(fd, F_SETLK, &fl) == -1) { + commd_debug(MD_MMV_SYSLOG, + "init_set: Cannot lock MCT '%s'\n", table_name); + if (fcntl(fd, F_GETLK, &fl) != -1) { + commd_debug(MD_MMV_SYSLOG, "rpc.mdcommd:" + "Process %d holds lock\n", fl.l_pid); + (void) close(fd); + } else { + commd_debug(MD_MMV_SYSLOG, "rpc.mdcommd:" + "F_GETLK failed\n"); + (void) close(fd); + return (-1); + } + + /* + * Try to terminate other mdcommd process so that we + * can establish ourselves. + */ + if (sigsend(P_PID, fl.l_pid, 0) == 0) { + if (sigsend(P_PID, fl.l_pid, SIGKILL) < 0) { + commd_debug(MD_MMV_SYSLOG, + "rpc.mdcommd:" + "SIGKILL of %d failed\n", fl.l_pid); + } else { + commd_debug(MD_MMV_SYSLOG, + "rpc.mdcommd:" + "Process %d killed\n", fl.l_pid); + } + } else { + commd_debug(MD_MMV_SYSLOG, "rpc.mdcommd:" + "Process %d not killable\n", fl.l_pid); + } + return (-1); + } + /* * To ensure that the file has the appropriate size, * we write a byte at the end of the file. */