PageRenderTime 27ms CodeModel.GetById 17ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 1ms

/src/modules/dshgroup.c

https://code.google.com/
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 */