1d6b92ffaSHans Petter Selasky /*
2d6b92ffaSHans Petter Selasky * Copyright (c) 2014 Intel Corporation. All Rights Reserved
3d6b92ffaSHans Petter Selasky *
4d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
5d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
6d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
7d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
8d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
9d6b92ffaSHans Petter Selasky *
10d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
11d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
12d6b92ffaSHans Petter Selasky * conditions are met:
13d6b92ffaSHans Petter Selasky *
14d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
15d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
16d6b92ffaSHans Petter Selasky * disclaimer.
17d6b92ffaSHans Petter Selasky *
18d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
19d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
20d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
21d6b92ffaSHans Petter Selasky * provided with the distribution.
22d6b92ffaSHans Petter Selasky *
23d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30d6b92ffaSHans Petter Selasky * SOFTWARE.
31d6b92ffaSHans Petter Selasky *
32d6b92ffaSHans Petter Selasky */
33d6b92ffaSHans Petter Selasky
34d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
35d6b92ffaSHans Petter Selasky # include <config.h>
36d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */
37d6b92ffaSHans Petter Selasky
38d6b92ffaSHans Petter Selasky #include <poll.h>
39d6b92ffaSHans Petter Selasky #include <sys/types.h>
40d6b92ffaSHans Petter Selasky #include <sys/stat.h>
41d6b92ffaSHans Petter Selasky #include <fcntl.h>
42d6b92ffaSHans Petter Selasky #include <assert.h>
43d6b92ffaSHans Petter Selasky #include <string.h>
44d6b92ffaSHans Petter Selasky #include <limits.h>
45d6b92ffaSHans Petter Selasky #include <stdio.h>
46d6b92ffaSHans Petter Selasky #include <syslog.h>
47d6b92ffaSHans Petter Selasky #include <dirent.h>
48d6b92ffaSHans Petter Selasky #include <errno.h>
49d6b92ffaSHans Petter Selasky #include <unistd.h>
50d6b92ffaSHans Petter Selasky #include <getopt.h>
51d6b92ffaSHans Petter Selasky #include <stdlib.h>
52d6b92ffaSHans Petter Selasky
53d6b92ffaSHans Petter Selasky #include <libudev.h>
54d6b92ffaSHans Petter Selasky
55d6b92ffaSHans Petter Selasky struct udev *udev;
56d6b92ffaSHans Petter Selasky struct udev_monitor *mon;
57d6b92ffaSHans Petter Selasky
58d6b92ffaSHans Petter Selasky #include "ibdiag_common.h"
59d6b92ffaSHans Petter Selasky
60d6b92ffaSHans Petter Selasky #define SYS_HOSTNAME "/proc/sys/kernel/hostname"
61d6b92ffaSHans Petter Selasky #define DEF_SYS_DIR "/sys"
62d6b92ffaSHans Petter Selasky char *sys_dir = DEF_SYS_DIR;
63d6b92ffaSHans Petter Selasky #define SYS_INFINIBAND "class/infiniband"
64d6b92ffaSHans Petter Selasky #define DEFAULT_RETRY_RATE 60
65d6b92ffaSHans Petter Selasky #define DEFAULT_RETRY_COUNT 0
66d6b92ffaSHans Petter Selasky #define DEFAULT_ND_FORMAT "%h %d"
67d6b92ffaSHans Petter Selasky
68d6b92ffaSHans Petter Selasky int failure_retry_rate = DEFAULT_RETRY_RATE;
69d6b92ffaSHans Petter Selasky int set_retry_cnt = DEFAULT_RETRY_COUNT;
70d6b92ffaSHans Petter Selasky int foreground = 0;
71d6b92ffaSHans Petter Selasky char *pidfile = NULL;
72d6b92ffaSHans Petter Selasky
newline_to_null(char * str)73d6b92ffaSHans Petter Selasky static void newline_to_null(char *str)
74d6b92ffaSHans Petter Selasky {
75d6b92ffaSHans Petter Selasky char *term = index(str, '\n');
76d6b92ffaSHans Petter Selasky if (term)
77d6b92ffaSHans Petter Selasky *term = '\0';
78d6b92ffaSHans Petter Selasky }
79d6b92ffaSHans Petter Selasky
strip_domain(char * str)80d6b92ffaSHans Petter Selasky static void strip_domain(char *str)
81d6b92ffaSHans Petter Selasky {
82d6b92ffaSHans Petter Selasky char *term = index(str, '.');
83d6b92ffaSHans Petter Selasky if (term)
84d6b92ffaSHans Petter Selasky *term = '\0';
85d6b92ffaSHans Petter Selasky }
86d6b92ffaSHans Petter Selasky
build_node_desc(char * dest,size_t len,const char * device,const char * hostname)87d6b92ffaSHans Petter Selasky static void build_node_desc(char *dest, size_t len,
88d6b92ffaSHans Petter Selasky const char *device, const char *hostname)
89d6b92ffaSHans Petter Selasky {
90d6b92ffaSHans Petter Selasky char *end = dest + len-1;
91d6b92ffaSHans Petter Selasky const char *field;
92d6b92ffaSHans Petter Selasky char *src = ibd_nd_format;
93d6b92ffaSHans Petter Selasky
94d6b92ffaSHans Petter Selasky while (*src && (dest < end)) {
95d6b92ffaSHans Petter Selasky if (*src != '%') {
96d6b92ffaSHans Petter Selasky *dest++ = *src++;
97d6b92ffaSHans Petter Selasky } else {
98d6b92ffaSHans Petter Selasky src++;
99d6b92ffaSHans Petter Selasky switch (*src) {
100d6b92ffaSHans Petter Selasky case 'h':
101d6b92ffaSHans Petter Selasky field = hostname;
102d6b92ffaSHans Petter Selasky while (*field && (*field != '.') && (dest < end))
103d6b92ffaSHans Petter Selasky *dest++ = *field++;
104d6b92ffaSHans Petter Selasky break;
105d6b92ffaSHans Petter Selasky case 'd':
106d6b92ffaSHans Petter Selasky field = device;
107d6b92ffaSHans Petter Selasky while (*field && (dest < end))
108d6b92ffaSHans Petter Selasky *dest++ = *field++;
109d6b92ffaSHans Petter Selasky break;
110d6b92ffaSHans Petter Selasky }
111d6b92ffaSHans Petter Selasky src++;
112d6b92ffaSHans Petter Selasky }
113d6b92ffaSHans Petter Selasky }
114d6b92ffaSHans Petter Selasky *dest = 0;
115d6b92ffaSHans Petter Selasky }
116d6b92ffaSHans Petter Selasky
update_node_desc(const char * device,const char * hostname,int force)117d6b92ffaSHans Petter Selasky static int update_node_desc(const char *device, const char *hostname, int force)
118d6b92ffaSHans Petter Selasky {
119d6b92ffaSHans Petter Selasky int rc;
120d6b92ffaSHans Petter Selasky char nd[128];
121d6b92ffaSHans Petter Selasky char new_nd[64];
122d6b92ffaSHans Petter Selasky char nd_file[PATH_MAX];
123d6b92ffaSHans Petter Selasky FILE *f;
124d6b92ffaSHans Petter Selasky
125d6b92ffaSHans Petter Selasky snprintf(nd_file, sizeof(nd_file), "%s/%s/%s/node_desc",
126d6b92ffaSHans Petter Selasky sys_dir, SYS_INFINIBAND, device);
127d6b92ffaSHans Petter Selasky nd_file[sizeof(nd_file)-1] = '\0';
128d6b92ffaSHans Petter Selasky
129d6b92ffaSHans Petter Selasky f = fopen(nd_file, "r+");
130d6b92ffaSHans Petter Selasky if (!f) {
131d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Failed to open %s\n", nd_file);
132d6b92ffaSHans Petter Selasky return -EIO;
133d6b92ffaSHans Petter Selasky }
134d6b92ffaSHans Petter Selasky
135d6b92ffaSHans Petter Selasky if (!fgets(nd, sizeof(nd), f)) {
136d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Failed to read %s\n", nd_file);
137d6b92ffaSHans Petter Selasky rc = -EIO;
138d6b92ffaSHans Petter Selasky goto error;
139d6b92ffaSHans Petter Selasky }
140d6b92ffaSHans Petter Selasky newline_to_null(nd);
141d6b92ffaSHans Petter Selasky
142d6b92ffaSHans Petter Selasky build_node_desc(new_nd, sizeof(new_nd), device, hostname);
143d6b92ffaSHans Petter Selasky
144d6b92ffaSHans Petter Selasky if (!force && strncmp(new_nd, nd, sizeof(new_nd)) == 0) {
145d6b92ffaSHans Petter Selasky syslog(LOG_INFO, "%s: no change (%s)\n", device, new_nd);
146d6b92ffaSHans Petter Selasky } else {
147d6b92ffaSHans Petter Selasky syslog(LOG_INFO, "%s: change (%s) -> (%s)\n",
148d6b92ffaSHans Petter Selasky device, nd, new_nd);
149d6b92ffaSHans Petter Selasky rewind(f);
150d6b92ffaSHans Petter Selasky fprintf(f, new_nd);
151d6b92ffaSHans Petter Selasky }
152d6b92ffaSHans Petter Selasky
153d6b92ffaSHans Petter Selasky rc = 0;
154d6b92ffaSHans Petter Selasky error:
155d6b92ffaSHans Petter Selasky fclose(f);
156d6b92ffaSHans Petter Selasky return rc;
157d6b92ffaSHans Petter Selasky }
158d6b92ffaSHans Petter Selasky
set_rdma_node_desc(const char * hostname,int force)159d6b92ffaSHans Petter Selasky static int set_rdma_node_desc(const char *hostname, int force)
160d6b92ffaSHans Petter Selasky {
161d6b92ffaSHans Petter Selasky DIR *class_dir;
162d6b92ffaSHans Petter Selasky struct dirent *dent;
163d6b92ffaSHans Petter Selasky char dev_dir[PATH_MAX];
164d6b92ffaSHans Petter Selasky
165d6b92ffaSHans Petter Selasky snprintf(dev_dir, sizeof(dev_dir), "%s/%s", sys_dir, SYS_INFINIBAND);
166d6b92ffaSHans Petter Selasky dev_dir[sizeof(dev_dir)-1] = '\0';
167d6b92ffaSHans Petter Selasky
168d6b92ffaSHans Petter Selasky class_dir = opendir(dev_dir);
169d6b92ffaSHans Petter Selasky if (!class_dir) {
170d6b92ffaSHans Petter Selasky syslog(LOG_INFO, "Failed to open %s", dev_dir);
171d6b92ffaSHans Petter Selasky return -ENOSYS;
172d6b92ffaSHans Petter Selasky }
173d6b92ffaSHans Petter Selasky
174d6b92ffaSHans Petter Selasky while ((dent = readdir(class_dir))) {
175d6b92ffaSHans Petter Selasky int retry = set_retry_cnt;
176d6b92ffaSHans Petter Selasky if (dent->d_name[0] == '.')
177d6b92ffaSHans Petter Selasky continue;
178d6b92ffaSHans Petter Selasky
179d6b92ffaSHans Petter Selasky while (update_node_desc(dent->d_name, hostname, force) && retry > 0) {
180d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "retrying set Node Description on %s\n",
181d6b92ffaSHans Petter Selasky dent->d_name);
182d6b92ffaSHans Petter Selasky retry--;
183d6b92ffaSHans Petter Selasky }
184d6b92ffaSHans Petter Selasky }
185d6b92ffaSHans Petter Selasky
186d6b92ffaSHans Petter Selasky closedir(class_dir);
187d6b92ffaSHans Petter Selasky return 0;
188d6b92ffaSHans Petter Selasky }
189d6b92ffaSHans Petter Selasky
read_hostname(int fd,char * name,size_t len)190d6b92ffaSHans Petter Selasky static int read_hostname(int fd, char *name, size_t len)
191d6b92ffaSHans Petter Selasky {
192d6b92ffaSHans Petter Selasky int rc;
193d6b92ffaSHans Petter Selasky memset(name, 0, len);
194d6b92ffaSHans Petter Selasky if (read(fd, name, len-1) >= 0) {
195d6b92ffaSHans Petter Selasky newline_to_null(name);
196d6b92ffaSHans Petter Selasky strip_domain(name);
197d6b92ffaSHans Petter Selasky rc = 0;
198d6b92ffaSHans Petter Selasky } else {
199d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Read %s Failed\n", SYS_HOSTNAME);
200d6b92ffaSHans Petter Selasky rc = -EIO;
201d6b92ffaSHans Petter Selasky }
202d6b92ffaSHans Petter Selasky return rc;
203d6b92ffaSHans Petter Selasky }
204d6b92ffaSHans Petter Selasky
process_opts(void * context,int ch,char * optarg)205d6b92ffaSHans Petter Selasky static int process_opts(void *context, int ch, char *optarg)
206d6b92ffaSHans Petter Selasky {
207d6b92ffaSHans Petter Selasky unsigned long tmp;
208d6b92ffaSHans Petter Selasky switch (ch) {
209d6b92ffaSHans Petter Selasky case 0:
210d6b92ffaSHans Petter Selasky pidfile = optarg;
211d6b92ffaSHans Petter Selasky break;
212d6b92ffaSHans Petter Selasky case 'f':
213d6b92ffaSHans Petter Selasky foreground = 1;
214d6b92ffaSHans Petter Selasky break;
215d6b92ffaSHans Petter Selasky case 't':
216d6b92ffaSHans Petter Selasky tmp = strtoul(optarg, NULL, 0);
217d6b92ffaSHans Petter Selasky if (tmp >= INT_MAX) {
218d6b92ffaSHans Petter Selasky syslog(LOG_ERR,
219d6b92ffaSHans Petter Selasky "Invalid retry rate specified: %lu s\n",
220d6b92ffaSHans Petter Selasky tmp);
221d6b92ffaSHans Petter Selasky } else {
222d6b92ffaSHans Petter Selasky failure_retry_rate = (int)tmp;
223d6b92ffaSHans Petter Selasky }
224d6b92ffaSHans Petter Selasky break;
225d6b92ffaSHans Petter Selasky case 'r':
226d6b92ffaSHans Petter Selasky tmp = strtoul(optarg, NULL, 0);
227d6b92ffaSHans Petter Selasky if (tmp >= INT_MAX) {
228d6b92ffaSHans Petter Selasky syslog(LOG_ERR,
229d6b92ffaSHans Petter Selasky "Invalid retry count specified: %lu\n",
230d6b92ffaSHans Petter Selasky tmp);
231d6b92ffaSHans Petter Selasky } else {
232d6b92ffaSHans Petter Selasky set_retry_cnt = (int)tmp;
233d6b92ffaSHans Petter Selasky }
234d6b92ffaSHans Petter Selasky break;
235d6b92ffaSHans Petter Selasky default:
236d6b92ffaSHans Petter Selasky return -1;
237d6b92ffaSHans Petter Selasky }
238d6b92ffaSHans Petter Selasky return 0;
239d6b92ffaSHans Petter Selasky }
240d6b92ffaSHans Petter Selasky
241d6b92ffaSHans Petter Selasky #define MSG_MAX 2048
udev_log_fn(struct udev * ud,int priority,const char * file,int line,const char * fn,const char * format,va_list args)242d6b92ffaSHans Petter Selasky static void udev_log_fn(struct udev *ud, int priority, const char *file, int line,
243d6b92ffaSHans Petter Selasky const char *fn, const char *format, va_list args)
244d6b92ffaSHans Petter Selasky {
245d6b92ffaSHans Petter Selasky int off = 0;
246d6b92ffaSHans Petter Selasky char msg[MSG_MAX];
247d6b92ffaSHans Petter Selasky off = snprintf(msg, MSG_MAX, "libudev: %s:%d %s",
248d6b92ffaSHans Petter Selasky file, line, fn);
249d6b92ffaSHans Petter Selasky if (off < MSG_MAX-1)
250d6b92ffaSHans Petter Selasky vsnprintf(msg+off, MSG_MAX-off, format, args);
251d6b92ffaSHans Petter Selasky syslog(LOG_ERR, msg);
252d6b92ffaSHans Petter Selasky }
253d6b92ffaSHans Petter Selasky
setup_udev(void)254d6b92ffaSHans Petter Selasky static void setup_udev(void)
255d6b92ffaSHans Petter Selasky {
256d6b92ffaSHans Petter Selasky udev = udev_new();
257d6b92ffaSHans Petter Selasky if (!udev) {
258d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "udev_new failed\n");
259d6b92ffaSHans Petter Selasky return;
260d6b92ffaSHans Petter Selasky }
261d6b92ffaSHans Petter Selasky
262d6b92ffaSHans Petter Selasky udev_set_log_fn(udev, udev_log_fn);
263d6b92ffaSHans Petter Selasky udev_set_log_priority(udev, LOG_INFO);
264d6b92ffaSHans Petter Selasky #if HAVE_UDEV_GET_SYS_PATH
265d6b92ffaSHans Petter Selasky sys_dir = (char *)udev_get_sys_path(udev);
266d6b92ffaSHans Petter Selasky #endif
267d6b92ffaSHans Petter Selasky }
268d6b92ffaSHans Petter Selasky
get_udev_fd(void)269d6b92ffaSHans Petter Selasky static int get_udev_fd(void)
270d6b92ffaSHans Petter Selasky {
271d6b92ffaSHans Petter Selasky mon = udev_monitor_new_from_netlink(udev, "udev");
272d6b92ffaSHans Petter Selasky if (!mon) {
273d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "udev monitoring failed\n");
274d6b92ffaSHans Petter Selasky return -1;
275d6b92ffaSHans Petter Selasky }
276d6b92ffaSHans Petter Selasky
277d6b92ffaSHans Petter Selasky udev_monitor_filter_add_match_subsystem_devtype(mon, "infiniband", NULL);
278d6b92ffaSHans Petter Selasky udev_monitor_enable_receiving(mon);
279d6b92ffaSHans Petter Selasky return udev_monitor_get_fd(mon);
280d6b92ffaSHans Petter Selasky }
281d6b92ffaSHans Petter Selasky
process_udev_event(int ud_fd,const char * hostname)282d6b92ffaSHans Petter Selasky static void process_udev_event(int ud_fd, const char *hostname)
283d6b92ffaSHans Petter Selasky {
284d6b92ffaSHans Petter Selasky struct udev_device *dev;
285d6b92ffaSHans Petter Selasky
286d6b92ffaSHans Petter Selasky dev = udev_monitor_receive_device(mon);
287d6b92ffaSHans Petter Selasky if (dev) {
288d6b92ffaSHans Petter Selasky const char *device = udev_device_get_sysname(dev);
289d6b92ffaSHans Petter Selasky const char *action = udev_device_get_action(dev);
290d6b92ffaSHans Petter Selasky
291d6b92ffaSHans Petter Selasky syslog(LOG_INFO, "Device event: %s, %s, %s\n",
292d6b92ffaSHans Petter Selasky udev_device_get_subsystem(dev),
293d6b92ffaSHans Petter Selasky device, action);
294d6b92ffaSHans Petter Selasky
295d6b92ffaSHans Petter Selasky if (device && action
296d6b92ffaSHans Petter Selasky && strncmp(action, "add", sizeof("add")) == 0)
297d6b92ffaSHans Petter Selasky update_node_desc(device, hostname, 1);
298d6b92ffaSHans Petter Selasky
299d6b92ffaSHans Petter Selasky udev_device_unref(dev);
300d6b92ffaSHans Petter Selasky }
301d6b92ffaSHans Petter Selasky }
302d6b92ffaSHans Petter Selasky
monitor(void)303d6b92ffaSHans Petter Selasky static void monitor(void)
304d6b92ffaSHans Petter Selasky {
305d6b92ffaSHans Petter Selasky char hostname[128];
306d6b92ffaSHans Petter Selasky int hn_fd;
307d6b92ffaSHans Petter Selasky int rc;
308d6b92ffaSHans Petter Selasky struct pollfd fds[2];
309d6b92ffaSHans Petter Selasky int numfds = 1;
310d6b92ffaSHans Petter Selasky int ud_fd;
311d6b92ffaSHans Petter Selasky
312d6b92ffaSHans Petter Selasky ud_fd = get_udev_fd();
313d6b92ffaSHans Petter Selasky if (ud_fd >= 0)
314d6b92ffaSHans Petter Selasky numfds = 2;
315d6b92ffaSHans Petter Selasky
316d6b92ffaSHans Petter Selasky while (1) {
317d6b92ffaSHans Petter Selasky hn_fd = open(SYS_HOSTNAME, O_RDONLY);
318d6b92ffaSHans Petter Selasky if (hn_fd < 0) {
319d6b92ffaSHans Petter Selasky syslog(LOG_ERR,
320d6b92ffaSHans Petter Selasky "Open %s Failed: retry in %d seconds\n",
321d6b92ffaSHans Petter Selasky SYS_HOSTNAME, failure_retry_rate);
322d6b92ffaSHans Petter Selasky sleep(failure_retry_rate);
323d6b92ffaSHans Petter Selasky continue;
324d6b92ffaSHans Petter Selasky }
325d6b92ffaSHans Petter Selasky
326d6b92ffaSHans Petter Selasky fds[0].fd = hn_fd;
327d6b92ffaSHans Petter Selasky fds[0].events = 0;
328d6b92ffaSHans Petter Selasky fds[0].revents = 0;
329d6b92ffaSHans Petter Selasky
330d6b92ffaSHans Petter Selasky fds[1].fd = ud_fd;
331d6b92ffaSHans Petter Selasky fds[1].events = POLLIN;
332d6b92ffaSHans Petter Selasky fds[1].revents = 0;
333d6b92ffaSHans Petter Selasky
334d6b92ffaSHans Petter Selasky rc = poll(fds, numfds, -1);
335d6b92ffaSHans Petter Selasky
336d6b92ffaSHans Petter Selasky if (rc > 0) {
337d6b92ffaSHans Petter Selasky if (read_hostname(hn_fd, hostname, sizeof(hostname)) != 0)
338d6b92ffaSHans Petter Selasky hostname[0] = '\0';
339d6b92ffaSHans Petter Selasky
340d6b92ffaSHans Petter Selasky if (fds[0].revents != 0)
341d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Hostname change: %s\n", hostname);
342d6b92ffaSHans Petter Selasky
343d6b92ffaSHans Petter Selasky if (fds[1].revents != 0)
344d6b92ffaSHans Petter Selasky process_udev_event(ud_fd, hostname);
345d6b92ffaSHans Petter Selasky
346d6b92ffaSHans Petter Selasky rc = set_rdma_node_desc((const char *)hostname, 0);
347d6b92ffaSHans Petter Selasky } else {
348d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Poll %s Failed\n", SYS_HOSTNAME);
349d6b92ffaSHans Petter Selasky rc = -EIO;
350d6b92ffaSHans Petter Selasky }
351d6b92ffaSHans Petter Selasky
352d6b92ffaSHans Petter Selasky close(hn_fd);
353d6b92ffaSHans Petter Selasky
354d6b92ffaSHans Petter Selasky if (rc)
355d6b92ffaSHans Petter Selasky sleep(failure_retry_rate);
356d6b92ffaSHans Petter Selasky }
357d6b92ffaSHans Petter Selasky }
358d6b92ffaSHans Petter Selasky
remove_pidfile(void)359d6b92ffaSHans Petter Selasky static void remove_pidfile(void)
360d6b92ffaSHans Petter Selasky {
361d6b92ffaSHans Petter Selasky if (pidfile)
362d6b92ffaSHans Petter Selasky unlink(pidfile);
363d6b92ffaSHans Petter Selasky }
364d6b92ffaSHans Petter Selasky
write_pidfile(void)365d6b92ffaSHans Petter Selasky static void write_pidfile(void)
366d6b92ffaSHans Petter Selasky {
367d6b92ffaSHans Petter Selasky FILE *f;
368d6b92ffaSHans Petter Selasky if (pidfile) {
369d6b92ffaSHans Petter Selasky remove_pidfile();
370d6b92ffaSHans Petter Selasky f = fopen(pidfile, "w");
371d6b92ffaSHans Petter Selasky if (f) {
372d6b92ffaSHans Petter Selasky fprintf(f, "%d\n", getpid());
373d6b92ffaSHans Petter Selasky fclose(f);
374d6b92ffaSHans Petter Selasky } else {
375d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Failed to write pidfile : %s\n",
376d6b92ffaSHans Petter Selasky pidfile);
377d6b92ffaSHans Petter Selasky exit(errno);
378d6b92ffaSHans Petter Selasky }
379d6b92ffaSHans Petter Selasky }
380d6b92ffaSHans Petter Selasky }
381d6b92ffaSHans Petter Selasky
main(int argc,char * argv[])382d6b92ffaSHans Petter Selasky int main(int argc, char *argv[])
383d6b92ffaSHans Petter Selasky {
384d6b92ffaSHans Petter Selasky int fd;
385d6b92ffaSHans Petter Selasky char hostname[128];
386d6b92ffaSHans Petter Selasky
387d6b92ffaSHans Petter Selasky openlog("rdma-ndd", LOG_PID | LOG_PERROR, LOG_DAEMON);
388d6b92ffaSHans Petter Selasky
389d6b92ffaSHans Petter Selasky const struct ibdiag_opt opts[] = {
390d6b92ffaSHans Petter Selasky {"retry_timer", 't', 1, "<retry_timer>",
391d6b92ffaSHans Petter Selasky "Length of time to sleep when system errors occur "
392d6b92ffaSHans Petter Selasky "when attempting to poll and or read the hostname "
393d6b92ffaSHans Petter Selasky "from the system.\n"},
394d6b92ffaSHans Petter Selasky {"retry_count", 'r', 1, "<retry_count>",
395d6b92ffaSHans Petter Selasky "Number of times to attempt to retry setting "
396d6b92ffaSHans Petter Selasky "of the node description on failure\n"},
397d6b92ffaSHans Petter Selasky {"foreground", 'f', 0, NULL, "run in the foreground instead of as a daemon\n"},
398d6b92ffaSHans Petter Selasky {"pidfile", 0, 1, "<pidfile>", "specify a pid file (daemon mode only)\n"},
399d6b92ffaSHans Petter Selasky {0}
400d6b92ffaSHans Petter Selasky };
401d6b92ffaSHans Petter Selasky
402d6b92ffaSHans Petter Selasky ibdiag_process_opts(argc, argv, NULL, "CPDLGtsKyevd", opts,
403d6b92ffaSHans Petter Selasky process_opts, "", NULL);
404d6b92ffaSHans Petter Selasky
405d6b92ffaSHans Petter Selasky if (!ibd_nd_format)
406d6b92ffaSHans Petter Selasky ibd_nd_format = DEFAULT_ND_FORMAT;
407d6b92ffaSHans Petter Selasky
408d6b92ffaSHans Petter Selasky if (!foreground) {
409d6b92ffaSHans Petter Selasky closelog();
410d6b92ffaSHans Petter Selasky openlog("rdma-ndd", LOG_PID, LOG_DAEMON);
411d6b92ffaSHans Petter Selasky if (daemon(0, 0) != 0) {
412d6b92ffaSHans Petter Selasky syslog(LOG_ERR, "Failed to daemonize\n");
413d6b92ffaSHans Petter Selasky exit(errno);
414d6b92ffaSHans Petter Selasky }
415d6b92ffaSHans Petter Selasky write_pidfile();
416d6b92ffaSHans Petter Selasky }
417d6b92ffaSHans Petter Selasky
418d6b92ffaSHans Petter Selasky setup_udev();
419d6b92ffaSHans Petter Selasky
420d6b92ffaSHans Petter Selasky syslog(LOG_INFO, "Node Descriptor format (%s)\n", ibd_nd_format);
421d6b92ffaSHans Petter Selasky
422d6b92ffaSHans Petter Selasky fd = open(SYS_HOSTNAME, O_RDONLY);
423d6b92ffaSHans Petter Selasky if (read_hostname(fd, hostname, sizeof(hostname)) != 0)
424d6b92ffaSHans Petter Selasky hostname[0] = '\0';
425d6b92ffaSHans Petter Selasky set_rdma_node_desc((const char *)hostname, 1);
426d6b92ffaSHans Petter Selasky close(fd);
427d6b92ffaSHans Petter Selasky
428d6b92ffaSHans Petter Selasky monitor();
429d6b92ffaSHans Petter Selasky
430d6b92ffaSHans Petter Selasky remove_pidfile();
431d6b92ffaSHans Petter Selasky
432d6b92ffaSHans Petter Selasky return 0;
433d6b92ffaSHans Petter Selasky }
434