1 // SPDX-License-Identifier: LGPL-2.1+
3 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
6 * Copyright (c) 2012, 2013, Intel Corporation.
9 * This file is part of Lustre, http://www.lustre.org/
11 * Author: Nathan Rutman <nathan.rutman@sun.com>
13 * Kernel <-> userspace communication routines.
14 * Using pipes for all arches.
22 #include <lustre/lustreapi.h>
24 #include "lustreapi_internal.h"
26 /** Start the userspace side of a KUC pipe.
27 * @param link Private descriptor for pipe/socket.
28 * @param groups KUC broadcast group to listen to
29 * (can be null for unicast to this pid)
30 * @param rfd_flags flags for read side of pipe (e.g. O_NONBLOCK)
32 int libcfs_ukuc_start(struct lustre_kernelcomm *link,
33 int group, int rfd_flags)
38 link->lk_rfd = link->lk_wfd = LK_NOFD;
43 if (fcntl(pfd[0], F_SETFL, rfd_flags) < 0) {
50 memset(link, 0, sizeof(*link));
51 link->lk_rfd = pfd[0];
52 link->lk_wfd = pfd[1];
53 link->lk_group = group;
54 link->lk_uid = getpid();
58 int libcfs_ukuc_stop(struct lustre_kernelcomm *link)
62 if (link->lk_wfd != LK_NOFD)
64 rc = close(link->lk_rfd);
65 link->lk_rfd = link->lk_wfd = LK_NOFD;
69 /** Returns the file descriptor for the read side of the pipe,
70 * to be used with poll/select.
71 * @param link Private descriptor for pipe/socket.
73 int libcfs_ukuc_get_rfd(struct lustre_kernelcomm *link)
78 #define lhsz sizeof(*kuch)
80 /** Read a message from the link.
81 * Allocates memory, returns handle
83 * @param link Private descriptor for pipe/socket.
84 * @param buf Buffer to read into, must include size for kuc_hdr
85 * @param maxsize Maximum message size allowed
86 * @param transport Only listen to messages on this transport
87 * (and the generic transport)
89 int libcfs_ukuc_msg_get(struct lustre_kernelcomm *link, char *buf, int maxsize,
95 memset(buf, 0, maxsize);
98 /* Read header first to get message size */
99 rc = read(link->lk_rfd, buf, lhsz);
104 kuch = (struct kuc_hdr *)buf;
106 if (kuch->kuc_magic != KUC_MAGIC) {
107 llapi_err_noerrno(LLAPI_MSG_ERROR,
108 "bad message magic %x != %x\n",
109 kuch->kuc_magic, KUC_MAGIC);
114 if (kuch->kuc_msglen > maxsize) {
120 rc = read(link->lk_rfd, buf + lhsz, kuch->kuc_msglen - lhsz);
125 if (rc < (kuch->kuc_msglen - lhsz)) {
126 llapi_err_noerrno(LLAPI_MSG_ERROR,
127 "short read: got %d of %d bytes\n",
128 rc, kuch->kuc_msglen);
133 if (kuch->kuc_transport == transport ||
134 kuch->kuc_transport == KUC_TRANSPORT_GENERIC) {
137 /* Drop messages for other transports */