1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2009 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * Author: Nathan Rutman <nathan.rutman@sun.com>
38 * Kernel <-> userspace communication routines. We'll use a shorthand term
39 * "lnl" (Lustre NetLink) for the interface names for all arches (even though
40 * implemtation may not use NetLink).
41 * For Linux, we use Netlink sockets.
44 #define DEBUG_SUBSYSTEM S_CLASS
47 /* This is the kernel side.
48 * See libcfs/ulinux/ulinux-kernelcomm.c for the user side.
51 #if defined(HAVE_NETLINK) && defined(__KERNEL__)
53 #include <linux/module.h>
54 #include <linux/socket.h>
55 #include <linux/skbuff.h>
56 #include <net/netlink.h>
58 #include <libcfs/libcfs.h>
60 /* Single Netlink Message type to send all Lustre messages */
63 static struct sock *lnl_socket = NULL;
64 static atomic_t lnl_start_count = ATOMIC_INIT(0);
65 static spinlock_t lnl_lock = SPIN_LOCK_UNLOCKED;
67 /** Start the netlink socket for this transport
68 * @param transport lnl_transport
70 int libcfs_klnl_start(int transport)
75 /* If anyone needs it, we can add per-transport incoming message
76 callbacks. Add the callback as a param here. Store the transport
77 and callback in a table. Include a generalized incoming msg
78 callback here to dispatch messages to the appropriate
79 per-transport callback. */
82 if (atomic_inc_return(&lnl_start_count) > 1)
85 lnl_socket = netlink_kernel_create(LNL_SOCKET, LNL_GRP_CNT,
86 NULL /* incoming cb */,
88 if (lnl_socket == NULL) {
89 CERROR("Cannot open socket %d\n", LNL_SOCKET);
90 atomic_dec(&lnl_start_count);
91 GOTO(out, rc = -ENODEV);
95 spin_unlock(&lnl_lock);
98 EXPORT_SYMBOL(libcfs_klnl_start);
100 static void send_shutdown_msg(int transport, int group) {
103 lh.lnl_magic = LNL_MAGIC;
104 lh.lnl_transport = LNL_TRANSPORT_GENERIC;
105 lh.lnl_msgtype = LNL_MSG_SHUTDOWN;
106 lh.lnl_msglen = sizeof(lh);
108 libcfs_klnl_msg_put(0, group, &lh);
111 /* This should be called once per (started) transport
112 * @param transport lnl_transport
113 * @param group Broadcast group for shutdown message */
114 int libcfs_klnl_stop(int transport, int group)
117 send_shutdown_msg(transport, group);
119 spin_lock(&lnl_lock);
121 if (atomic_dec_and_test(&lnl_start_count)) {
122 sock_release(lnl_socket->sk_socket);
126 spin_unlock(&lnl_lock);
129 EXPORT_SYMBOL(libcfs_klnl_stop);
131 static struct sk_buff *netlink_make_msg(int pid, int seq, void *payload,
135 struct nlmsghdr *nlh;
136 int len = NLMSG_SPACE(size);
139 skb = nlmsg_new(len, GFP_KERNEL);
143 nlh = nlmsg_put(skb, pid, seq, LNL_MSG, size, 0);
149 data = nlmsg_data(nlh);
150 memcpy(data, payload, size);
155 * libcfs_klnl_msg_put - send an message from kernel to userspace
156 * @param pid Process id to send message to for unicast messages; must be 0 for
158 * @param group Broadcast group; 0 for unicast messages
159 * @param payload Payload data. First field of payload is always struct lnl_hdr
161 * Allocates an skb, builds the netlink message, and sends it to the pid.
163 int libcfs_klnl_msg_put(int pid, int group, void *payload)
165 struct lnl_hdr *lnlh = (struct lnl_hdr *)payload;
169 if (lnl_socket == NULL) {
170 CERROR("LustreNetLink: not running\n");
174 if (lnlh->lnl_magic != LNL_MAGIC) {
175 CERROR("LustreNetLink: bad magic %x\n", lnlh->lnl_magic);
179 if ((pid != 0) && (group != 0)) {
180 CERROR("LustreNetLink: pid=%d or group=%d must be 0\n",
185 skb = netlink_make_msg(pid, 0, payload, lnlh->lnl_msglen);
190 rc = nlmsg_unicast(lnl_socket, skb, pid);
192 rc = nlmsg_multicast(lnl_socket, skb, 0, group);
194 CDEBUG(0, "Sent message pid=%d, group=%d, rc=%d\n", pid, group, rc);
197 CWARN("message send failed (%d) [pid=%d,group=%d]\n", rc,
202 EXPORT_SYMBOL(libcfs_klnl_msg_put);