PageRenderTime 35ms CodeModel.GetById 19ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

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