/src/modules/rms.c

https://code.google.com/ · C · 180 lines · 84 code · 24 blank · 72 comment · 7 complexity · 262b46de9020d7d305b0530f074efa12 MD5 · raw file

  1. /*****************************************************************************\
  2. * $Id$
  3. *****************************************************************************
  4. * Copyright (C) 2001-2006 The Regents of the University of California.
  5. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  6. * Written by Jim Garlick <garlick@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. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "src/common/hostlist.h"
  33. #include "src/common/err.h"
  34. #include "src/common/xmalloc.h"
  35. #include "src/common/xstring.h"
  36. #include "src/pdsh/xpopen.h"
  37. #include "src/pdsh/mod.h"
  38. #if STATIC_MODULES
  39. # define pdsh_module_info rms_module_info
  40. # define pdsh_module_priority rms_module_priority
  41. #endif
  42. int pdsh_module_priority = 10;
  43. /*
  44. * Call this module after all option processing. The module will only
  45. * try to read the RMS_RESOURCEID if opt->wcoll is not already set.
  46. * Calling the module in postop allows us to be sure that all other
  47. * modules had a chance to update the wcoll.
  48. */
  49. static int mod_rms_postop(opt_t *opt);
  50. static hostlist_t _rms_rid_to_nodes(char *part, int rid);
  51. static hostlist_t _rms_wcoll(void);
  52. /*
  53. * Export generic pdsh module options
  54. */
  55. struct pdsh_module_operations rms_module_ops = {
  56. (ModInitF) NULL,
  57. (ModExitF) NULL,
  58. (ModReadWcollF) NULL,
  59. (ModPostOpF) mod_rms_postop
  60. };
  61. /*
  62. * Export rcmd module operations
  63. */
  64. struct pdsh_rcmd_operations rms_rcmd_ops = {
  65. (RcmdInitF) NULL,
  66. (RcmdSigF) NULL,
  67. (RcmdF) NULL,
  68. };
  69. /*
  70. * Export module options
  71. */
  72. struct pdsh_module_option rms_module_options[] =
  73. {
  74. PDSH_OPT_TABLE_END
  75. };
  76. /*
  77. * Rms module info
  78. */
  79. struct pdsh_module pdsh_module_info = {
  80. "misc",
  81. "rms",
  82. "Jim Garlick <garlick@llnl.gov>",
  83. "Attempt to read wcoll from RMS_RESOURCEID env var",
  84. DSH | PCP,
  85. &rms_module_ops,
  86. &rms_rcmd_ops,
  87. &rms_module_options[0],
  88. };
  89. /*
  90. * If no wcoll has been established by this time, look for the
  91. * RMS_RESOURCE env var, and set wcoll to the list of nodes allocated
  92. * to that resource.
  93. */
  94. static int mod_rms_postop(opt_t *opt)
  95. {
  96. if (opt->wcoll)
  97. return 0;
  98. opt->wcoll = _rms_wcoll();
  99. return 0;
  100. }
  101. /*
  102. * Helper for rms_wcoll() - RMS provides no API to get the list of nodes
  103. * once allocated, so we query the msql database with 'rmsquery'.
  104. * part (IN) partition name
  105. * rid (IN) resource id
  106. * result (RETURN) NULL or a list of hostnames
  107. */
  108. static hostlist_t _rms_rid_to_nodes(char *part, int rid)
  109. {
  110. FILE *f;
  111. char tmp[256];
  112. /* XXX how to specify partition? do we need to? */
  113. snprintf(tmp, sizeof(tmp),
  114. "%s \"select hostnames from resources where name='%d'\"",
  115. _PATH_RMSQUERY, rid);
  116. f = xpopen(tmp, "r");
  117. if (f == NULL)
  118. errx("%p: error running %s\n", _PATH_RMSQUERY);
  119. *tmp = '\0';
  120. while (fgets(tmp, sizeof(tmp), f) != NULL);
  121. xpclose(f);
  122. /* should either have empty string or host[n-m] range */
  123. /* turn elanid range into list of hostnames */
  124. xstrcln(tmp, "\r\n\t "); /* drop trailing \n */
  125. return hostlist_create(tmp);
  126. }
  127. /*
  128. * If RMS_RESOURCE is set, return wcoll corresponding to RMS res allocation.
  129. * result (RETURN) NULL or a list of hostnames
  130. */
  131. static hostlist_t _rms_wcoll(void)
  132. {
  133. char *rhs;
  134. hostlist_t result = NULL;
  135. /* extract partition and resource ID from environment, if present */
  136. if ((rhs = getenv("RMS_RESOURCEID"))) {
  137. char *part, *ridstr = strchr(rhs, '.');
  138. int rid;
  139. if (!ridstr)
  140. errx("%p: malformed RMS_RESOURCEID value\n");
  141. *ridstr++ = '\0';
  142. rid = atoi(ridstr);
  143. part = rhs;
  144. result = _rms_rid_to_nodes(part, rid);
  145. }
  146. /*
  147. * Depend on PAM to keep user from setting RMS_RESOURCEID to
  148. * someone else's allocation and stealing cycles. pam_rms should
  149. * check to see if user has allocated the node before allowing qshd
  150. * authorization to succede.
  151. */
  152. return result;
  153. }
  154. /*
  155. * vi: tabstop=4 shiftwidth=4 expandtab
  156. */