예제 #1
0
static void
release_lockspaces(bool force)
{
	struct lockspace *ls;

	for (ls = lockspaces; ls; ls = ls->next)
		release_lockspace(ls, force);
}
예제 #2
0
파일: libdlm.c 프로젝트: beekhof/dlm
int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
{
	char dev_path[PATH_MAX];
	struct stat st;
	struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
	uint32_t flags = 0;
	int fd, is_symlink = 0;

	ls_dev_name(name, dev_path, sizeof(dev_path));
	if (!lstat(dev_path, &st) && S_ISLNK(st.st_mode))
		is_symlink = 1;

	/* We need the minor number */
	if (fstat(lsinfo->fd, &st))
		return -1;

	/* Close the lockspace first if it's in use */
	ls_pthread_cleanup(lsinfo);

	if (open_control_device())
		return -1;

	if (force)
		flags = DLM_USER_LSFLG_FORCEFREE;

	release_lockspace(minor(st.st_rdev), flags);

	if (!is_symlink)
		return 0;

	/* The following open is used to detect if our release was the last.
	   It will fail if our release was the last, because either:
	   . udev has already removed the truncated sysfs device name (ENOENT)
	   . the misc device has been deregistered in the kernel (ENODEV)
	     (the deregister completes before release returns)

	   So, if the open fails, we know that our release was the last,
	   udev will be removing the device with the truncated name (if it
	   hasn't already), and we should remove the symlink. */

	fd = open(dev_path, O_RDWR);
	if (fd < 0)
		unlink(dev_path);
	else
		close(fd); /* our release was not the last */

	return 0;
}
예제 #3
0
/*
 * A network connection should be closed because EOF was reached, an error
 * occurred, or because a MSG_CLOSE message was received.  If the primary
 * connection to a node is lost, the cluster has degenerated and we shut
 * all lockspaces down.
 */
static void
proto_close(int fd, struct node *node)
{
	close(fd);
	remove_poll_callback(&cbs, fd);
	if (node->outgoing_fd == fd) {
		struct lockspace *ls;

		node->outgoing_fd = -1;
		connected_nodes &= ~node_mask(node);
		for (ls = lockspaces; ls; ls = ls->next) {
			ls->joining = 0;
			ls->leaving = ls->members & ~node_mask(local_node);
			if (ls->leaving)
				update_lockspace(ls);
			if (ls->members & node_mask(local_node))
				release_lockspace(ls, true);
		}
	}
}