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