/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. #if HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #ifndef DSHGROUP_PATH
  30. #define DSHGROUP_PATH "/etc/dsh/group"
  31. #endif
  32. #include <unistd.h> /* access */
  33. #include <stdlib.h> /* getenv */
  34. #include <string.h>
  35. #include "src/pdsh/wcoll.h"
  36. #include "src/pdsh/mod.h"
  37. #include "src/common/hostlist.h"
  38. #include "src/common/xmalloc.h"
  39. #include "src/common/err.h"
  40. #include "src/common/list.h"
  41. #include "src/common/split.h"
  42. #if STATIC_MODULES
  43. # define pdsh_module_info dshgroup_module_info
  44. # define pdsh_module_priority dshgroup_module_priority
  45. #endif
  46. int pdsh_module_priority = DEFAULT_MODULE_PRIORITY;
  47. static hostlist_t read_groupfile(opt_t *opt);
  48. static int dshgroup_postop (opt_t *);
  49. static int dshgroup_process_opt(opt_t *, int, char *);
  50. static List groups = NULL;
  51. static List exgroups = NULL;
  52. /*
  53. * Export pdsh module operations structure
  54. */
  55. struct pdsh_module_operations dshgroup_module_ops = {
  56. (ModInitF) NULL,
  57. (ModExitF) NULL,
  58. (ModReadWcollF) read_groupfile,
  59. (ModPostOpF) dshgroup_postop,
  60. };
  61. /*
  62. * Export rcmd module operations
  63. */
  64. struct pdsh_rcmd_operations dshgroup_rcmd_ops = {
  65. (RcmdInitF) NULL,
  66. (RcmdSigF) NULL,
  67. (RcmdF) NULL,
  68. };
  69. /*
  70. * Export module options
  71. */
  72. struct pdsh_module_option dshgroup_module_options[] =
  73. { { 'g', "groupname", "target hosts in dsh group \"groupname\"",
  74. DSH | PCP, (optFunc) dshgroup_process_opt },
  75. { 'X', "groupname", "exclude hosts in dsh group \"groupname\"",
  76. DSH | PCP, (optFunc) dshgroup_process_opt },
  77. PDSH_OPT_TABLE_END
  78. };
  79. /*
  80. * Machines module info
  81. */
  82. struct pdsh_module pdsh_module_info = {
  83. "misc",
  84. "dshgroup",
  85. "Mark Grondona <mgrondona@llnl.gov>",
  86. "Read list of targets from dsh-style \"group\" files",
  87. DSH | PCP,
  88. &dshgroup_module_ops,
  89. &dshgroup_rcmd_ops,
  90. &dshgroup_module_options[0],
  91. };
  92. static int dshgroup_process_opt(opt_t *pdsh_opt, int opt, char *arg)
  93. {
  94. switch (opt) {
  95. case 'g':
  96. groups = list_split_append (groups, ",", arg);
  97. break;
  98. case 'X':
  99. exgroups = list_split_append (exgroups, ",", arg);
  100. break;
  101. default:
  102. err ("%p: dshgroup_process_opt: invalid option `%c'\n", opt);
  103. return -1;
  104. break;
  105. }
  106. return 0;
  107. }
  108. static hostlist_t _read_groupfile (const char *group)
  109. {
  110. int maxpathlen;
  111. char path [4096];
  112. char *home = getenv("HOME");
  113. char *dshgroup_path = getenv("DSHGROUP_PATH");
  114. maxpathlen = sizeof (path) - 1;
  115. if (!dshgroup_path)
  116. dshgroup_path = DSHGROUP_PATH;
  117. if (home) {
  118. int n;
  119. n = snprintf (path, maxpathlen,"%s/.dsh/group:%s", home, dshgroup_path);
  120. if (n <= 0 || n > maxpathlen)
  121. errx ("%p: dshgroup: search path (%s/.dsh/group:%s) overflow\n",
  122. home, dshgroup_path);
  123. }
  124. else {
  125. err ("%p: dshgroup: warning: Unable to read $HOME env var\n");
  126. strncpy (path, dshgroup_path, sizeof (path));
  127. }
  128. return read_wcoll_path (path, group);
  129. }
  130. static hostlist_t _read_groups (List grouplist)
  131. {
  132. ListIterator i = NULL;
  133. hostlist_t hl = NULL;
  134. char *group;
  135. i = list_iterator_create (grouplist);
  136. while ((group = list_next (i))) {
  137. hostlist_t l = _read_groupfile (group);
  138. if (l == NULL)
  139. continue;
  140. if (hl == NULL) {
  141. hl = l;
  142. } else {
  143. hostlist_push_list (hl, l);
  144. hostlist_destroy (l);
  145. }
  146. }
  147. list_iterator_destroy (i);
  148. if (hl != NULL)
  149. hostlist_uniq (hl);
  150. return (hl);
  151. }
  152. static hostlist_t read_groupfile(opt_t *opt)
  153. {
  154. if (!groups)
  155. return NULL;
  156. if (opt->wcoll && groups)
  157. errx("Do not specify both -w and -g");
  158. return _read_groups (groups);
  159. }
  160. static int
  161. _delete_all (hostlist_t hl, hostlist_t dl)
  162. {
  163. int rc = 0;
  164. char * host = NULL;
  165. hostlist_iterator_t i = hostlist_iterator_create (dl);
  166. while ((host = hostlist_next (i))) {
  167. rc += hostlist_delete_host (hl, host);
  168. free (host);
  169. }
  170. hostlist_iterator_destroy (i);
  171. return (rc);
  172. }
  173. static int dshgroup_postop (opt_t *opt)
  174. {
  175. hostlist_t hl = NULL;
  176. if (!opt->wcoll || !exgroups)
  177. return (0);
  178. if ((hl = _read_groups (exgroups)) == NULL)
  179. return (0);
  180. _delete_all (opt->wcoll, hl);
  181. return 0;
  182. }
  183. /*
  184. * vi: tabstop=4 shiftwidth=4 expandtab
  185. */