Show misc_sim.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* misc_sim: Simulator support for em* software. These functions help
* to fake certain parts of the environment (e.g., getting node ID)
* when we're running inside the simulator.
*
* $Id: misc_sim.c,v 1.16 2005/04/01 04:59:25 girod Exp $
*/
char misc_sim_cvsid[] = "$Id: misc_sim.c,v 1.16 2005/04/01 04:59:25 girod Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/time.h>
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <misc.h>
#include "emrun/emsim.h"
/*
* device name munging for simulation
*/
int in_sim = 0;
#define SIM_PATH_RINGSIZE 5
static char *sim_path_ring[SIM_PATH_RINGSIZE];
static int sim_path_index = 0;
static int mangling_disabled = 0;
int sim_is_component()
{
return in_sim && (my_node_id == SIM_COMPONENT_ID);
}
void sim_path_disable() { mangling_disabled = 1; }
void sim_path_enable() { mangling_disabled = 0; }
static char *sim_path_aux(char *orig_path, int no_node_id)
{
char *dest;
char groupname[30], nodename[30];
if ((orig_path == NULL) || (strlen(orig_path) == 0)) {
elog(LOG_CRIT, "sim_path passed empty or null string!");
exit(1);
}
/* there are certain special cases where programs that know what
* they're doing need to selectively enable/disable path mangling.
* Motenic is an example: it opens global (non-mangled) hostmote
* devices, then registers per-node (mangled) motenic devices. */
if (mangling_disabled)
return orig_path;
if (!in_sim && (my_sim_group == 0))
return orig_path;
if (my_sim_group)
sprintf(groupname, "group%d/", my_sim_group);
else
*groupname = '\0';
if (no_node_id || sim_is_component() || !in_sim)
*nodename = '\0';
else
sprintf(nodename, "node%03d/", my_node_id);
sim_path_index = (sim_path_index + 1) % SIM_PATH_RINGSIZE;
if (sim_path_ring[sim_path_index] == NULL)
sim_path_ring[sim_path_index] = (char*)malloc(PATH_MAX+1);
dest = sim_path_ring[sim_path_index];
/* add a prefix to anything in /dev */
if (!strncmp(orig_path, "/dev/", strlen("/dev/"))) {
sprintf(dest, "/dev/sim/%s%s%s", groupname, nodename,
orig_path+strlen("/dev/"));
return dest;
}
/* write /etc files into /tmp/sim instead */
if (!strncmp(orig_path, "/etc/", strlen("/etc/"))) {
sprintf(dest, "/tmp/sim/%s%setc/", groupname, nodename);
if (mkdir_with_parents(dest) < 0) {
elog(LOG_ERR, "can't mkdir %s: %m", dest);
exit(1);
}
strcat(dest, orig_path + strlen("/etc/"));
return dest;
}
/* return path unmodified */
return orig_path;
}
char *sim_path(char *orig_path)
{
return sim_path_aux(orig_path, 0);
}
char *group_path(char *orig_path)
{
return sim_path_aux(orig_path, 1);
}
#define MAX_STACK 10
static node_id_t stack[MAX_STACK] = {};
static int stack_ptr = 0;
int sim_become_node(node_id_t id)
{
if (stack_ptr < MAX_STACK) {
stack[stack_ptr++] = my_node_id;
my_node_id = id;
return 0;
}
elog(LOG_WARNING, "stack overflow!");
return -1;
}
int sim_restore_node()
{
if (stack_ptr > 0) {
my_node_id = stack[--stack_ptr];
return 0;
}
elog(LOG_WARNING, "stack underflow!");
return -1;
}
/* various bits of initialization we need to do if we are running in
* simulator */
void sim_init(char *proc_title)
{
char buf[30];
in_sim = 1;
if (!sim_is_component()) {
sprintf(buf, "[%d]", my_node_id);
memcpy(proc_title, buf, i_min(strlen(proc_title), strlen(buf)));
}
}
char *misc_sim_get_proxy_host(char *link_name, int *argc, char **argv)
{
char *host = misc_parse_out_option(argc, argv, "proxy-host", 0);
if (host == NULL) host = getenv("SIM_PROXY_HOST");
if (host) {
elog(LOG_NOTICE, "Ceiling mode: Proxy-host set to remote host %s!", host);
}
return host;
}
See more files for this project here