/src/modules/dshgroup.c
C | 222 lines | 145 code | 37 blank | 40 comment | 22 complexity | 7b0c7f69fc20796ba47ca4aa8e74c631 MD5 | raw file
1/*****************************************************************************\ 2 * $Id$ 3 ***************************************************************************** 4 * Copyright (C) 2005-2006 The Regents of the University of California. 5 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 6 * Written by Mark Grondona <mgrondona@llnl.gov> 7 * UCRL-CODE-2003-005. 8 * 9 * This file is part of Pdsh, a parallel remote shell program. 10 * For details, see <http://www.llnl.gov/linux/pdsh/>. 11 * 12 * Pdsh is free software; you can redistribute it and/or modify it under 13 * the terms of the GNU General Public License as published by the Free 14 * Software Foundation; either version 2 of the License, or (at your option) 15 * any later version. 16 * 17 * Pdsh is distributed in the hope that it will be useful, but WITHOUT ANY 18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 20 * details. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with Pdsh; if not, write to the Free Software Foundation, Inc., 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25\*****************************************************************************/ 26 27#if HAVE_CONFIG_H 28# include "config.h" 29#endif 30 31#ifndef DSHGROUP_PATH 32#define DSHGROUP_PATH "/etc/dsh/group" 33#endif 34 35#include <unistd.h> /* access */ 36#include <stdlib.h> /* getenv */ 37#include <string.h> 38 39#include "src/pdsh/wcoll.h" 40#include "src/pdsh/mod.h" 41#include "src/common/hostlist.h" 42#include "src/common/xmalloc.h" 43#include "src/common/err.h" 44#include "src/common/list.h" 45#include "src/common/split.h" 46 47#if STATIC_MODULES 48# define pdsh_module_info dshgroup_module_info 49# define pdsh_module_priority dshgroup_module_priority 50#endif 51 52int pdsh_module_priority = DEFAULT_MODULE_PRIORITY; 53 54static hostlist_t read_groupfile(opt_t *opt); 55static int dshgroup_postop (opt_t *); 56static int dshgroup_process_opt(opt_t *, int, char *); 57 58static List groups = NULL; 59static List exgroups = NULL; 60 61/* 62 * Export pdsh module operations structure 63 */ 64struct pdsh_module_operations dshgroup_module_ops = { 65 (ModInitF) NULL, 66 (ModExitF) NULL, 67 (ModReadWcollF) read_groupfile, 68 (ModPostOpF) dshgroup_postop, 69}; 70 71/* 72 * Export rcmd module operations 73 */ 74struct pdsh_rcmd_operations dshgroup_rcmd_ops = { 75 (RcmdInitF) NULL, 76 (RcmdSigF) NULL, 77 (RcmdF) NULL, 78}; 79 80/* 81 * Export module options 82 */ 83struct pdsh_module_option dshgroup_module_options[] = 84 { { 'g', "groupname", "target hosts in dsh group \"groupname\"", 85 DSH | PCP, (optFunc) dshgroup_process_opt }, 86 { 'X', "groupname", "exclude hosts in dsh group \"groupname\"", 87 DSH | PCP, (optFunc) dshgroup_process_opt }, 88 PDSH_OPT_TABLE_END 89 }; 90 91/* 92 * Machines module info 93 */ 94struct pdsh_module pdsh_module_info = { 95 "misc", 96 "dshgroup", 97 "Mark Grondona <mgrondona@llnl.gov>", 98 "Read list of targets from dsh-style \"group\" files", 99 DSH | PCP, 100 &dshgroup_module_ops, 101 &dshgroup_rcmd_ops, 102 &dshgroup_module_options[0], 103}; 104 105static int dshgroup_process_opt(opt_t *pdsh_opt, int opt, char *arg) 106{ 107 switch (opt) { 108 case 'g': 109 groups = list_split_append (groups, ",", arg); 110 break; 111 case 'X': 112 exgroups = list_split_append (exgroups, ",", arg); 113 break; 114 default: 115 err ("%p: dshgroup_process_opt: invalid option `%c'\n", opt); 116 return -1; 117 break; 118 } 119 return 0; 120} 121 122static hostlist_t _read_groupfile (const char *group) 123{ 124 int maxpathlen; 125 char path [4096]; 126 char *home = getenv("HOME"); 127 char *dshgroup_path = getenv("DSHGROUP_PATH"); 128 129 maxpathlen = sizeof (path) - 1; 130 131 if (!dshgroup_path) 132 dshgroup_path = DSHGROUP_PATH; 133 134 if (home) { 135 int n; 136 n = snprintf (path, maxpathlen,"%s/.dsh/group:%s", home, dshgroup_path); 137 if (n <= 0 || n > maxpathlen) 138 errx ("%p: dshgroup: search path (%s/.dsh/group:%s) overflow\n", 139 home, dshgroup_path); 140 } 141 else { 142 err ("%p: dshgroup: warning: Unable to read $HOME env var\n"); 143 strncpy (path, dshgroup_path, sizeof (path)); 144 } 145 146 return read_wcoll_path (path, group); 147} 148 149static hostlist_t _read_groups (List grouplist) 150{ 151 ListIterator i = NULL; 152 hostlist_t hl = NULL; 153 char *group; 154 155 i = list_iterator_create (grouplist); 156 157 while ((group = list_next (i))) { 158 hostlist_t l = _read_groupfile (group); 159 160 if (l == NULL) 161 continue; 162 163 if (hl == NULL) { 164 hl = l; 165 } else { 166 hostlist_push_list (hl, l); 167 hostlist_destroy (l); 168 } 169 } 170 171 list_iterator_destroy (i); 172 173 if (hl != NULL) 174 hostlist_uniq (hl); 175 176 return (hl); 177} 178 179static hostlist_t read_groupfile(opt_t *opt) 180{ 181 if (!groups) 182 return NULL; 183 184 if (opt->wcoll && groups) 185 errx("Do not specify both -w and -g"); 186 187 return _read_groups (groups); 188} 189 190static int 191_delete_all (hostlist_t hl, hostlist_t dl) 192{ 193 int rc = 0; 194 char * host = NULL; 195 hostlist_iterator_t i = hostlist_iterator_create (dl); 196 197 while ((host = hostlist_next (i))) { 198 rc += hostlist_delete_host (hl, host); 199 free (host); 200 } 201 hostlist_iterator_destroy (i); 202 return (rc); 203} 204 205static int dshgroup_postop (opt_t *opt) 206{ 207 hostlist_t hl = NULL; 208 209 if (!opt->wcoll || !exgroups) 210 return (0); 211 212 if ((hl = _read_groups (exgroups)) == NULL) 213 return (0); 214 215 _delete_all (opt->wcoll, hl); 216 217 return 0; 218} 219 220/* 221 * vi: tabstop=4 shiftwidth=4 expandtab 222 */