Package com.sun.faban.harness.engine

Source Code of com.sun.faban.harness.engine.ServerConfig

/* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.sun.com/cddl/cddl.html or
* install_dir/legal/LICENSE
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at install_dir/legal/LICENSE.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id$
*
* Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved
*/
package com.sun.faban.harness.engine;

import com.sun.faban.common.Command;
import com.sun.faban.common.CommandHandle;
import com.sun.faban.harness.ConfigurationException;
import com.sun.faban.harness.ParamRepository;
import com.sun.faban.harness.common.Config;
import com.sun.faban.harness.common.Run;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Class: ServerConfig.java
* This class manages the configuration of the server machines.
* It provides methods to capture system configuration, change
* the number of processors, get system log messages during a
* benchmark run, etc.
* WARNING: It is specific to Solaris and non-portable.
*
* @see GenericBenchmark
* @author Ramesh Ramachandran
*/
class ServerConfig {
    Run run;
    ParamRepository par;
    static String linesep = "<hr>";
    String master;
    CmdService cmds;
    Logger logger;
    List<ParamRepository.HostConfig> hostConfigs;

    public ServerConfig(Run r, ParamRepository par)
            throws ConfigurationException {
        this.par = par;
        run = r;
        cmds = CmdService.getHandle();
        logger = Logger.getLogger(this.getClass().getName());
        master = CmdService.getHandle().getMaster();
        hostConfigs = par.getHostConfigs();
    }

    /**
     * Get system configuration
     * This method retrieves the various system parameters from the
     * ParamRepository.
     * It gather /etc/system, prtdiag, psrinfo, uname, ps , vxprint
     * info from the server machines and logs them to the system log.
     * @return Whether the system configuration was successfully obtained.
     */
    public boolean get() {
        // Generate name of system log file - system.log
        String syslogfile = run.getOutDir() + "sysinfo.";
        boolean success = true;

        for(ParamRepository.HostConfig hostConfig : hostConfigs) {
            for (String host : hostConfig.hosts) {
                String machineName = cmds.getHostName(host);
                try {
                    File f = new File(syslogfile + machineName + ".html");

                    // In case we have multiple interfaces, the file may
                    // already exist. We don't want to spend the time doing
                    // the same thing over and over again.
                    if (f.exists())
                        continue;

                    // Get system info
                    PrintStream syslog =
                                    new PrintStream(new FileOutputStream(f));
                    Command sysinfo = new Command("sysinfo");
                    sysinfo.setStreamHandling(Command.STDOUT, Command.CAPTURE);
                    CommandHandle handle = cmds.execute(host, sysinfo, null);
                    byte[] info = handle.fetchOutput(Command.STDOUT);

                    // Write header and info to file.
                    syslog.println("<html><head><title>System Info for Server "
                            + machineName + "</title></head><body>");

                    syslog.write(info);

                    // Get User Commands output if specified
                    if (hostConfig.userCommands != null &&
                            hostConfig.userCommands.trim().length() > 0) {
                        String[] cmdStrings = hostConfig.userCommands.
                                                            split(";");
                        for (String cmdString : cmdStrings) {
                            Command c = new Command(cmdString);
                            c.setStreamHandling(Command.STDOUT,Command.CAPTURE);
                            logger.info("Executing '" + cmdString + "'");
                            handle = cmds.execute(host, c, null);
                            info = handle.fetchOutput(Command.STDOUT);
                            if (info != null) {
                                syslog.println(linesep);
                                syslog.println("<h3>" + hostConfig.userCommands+
                                        " on server " + machineName + "</h3>");
                                syslog.println("<pre>\n");
                                syslog.write(info);
                                syslog.println("\n</pre>");
                            }
                        }
                    }
                    syslog.println("</body></html>");
                    syslog.close();
                } catch (Exception e) {
                    logger.log(Level.SEVERE, "Failed to collect system info " +
                                            "for host " + machineName + '.', e);
                    success = false;
                }
            }
        }
        return success;
    }

    /**
     * Set system configuration.
     * Currently the only thing we set is the number of cpus.
     * @param cmds object to use
     * @return true/false depending on whether we were successful or not
     */
    public boolean set(CmdService cmds) {

        for (ParamRepository.HostConfig hostConfig : hostConfigs) {
            String[] hosts = hostConfig.hosts;
            int[] cpus = hostConfig.numCpus;
            int numCPUs = 0;

            if (cpus == null)
                continue;

            if (cpus.length == 1 && cpus[0] == 0)
                continue;

            // cpus can be of size 0 - don't set it, 1 - set the same for all,
            // or the number of hosts.
            if (cpus.length > 1 && cpus.length != hosts.length) {
                logger.severe("Entries in the \"cpus\" field must be 1 or " +
                        "the number of hosts, or blank. CPU entry mismatch. " +
                        "Please check configuration.");
                return false;
            }

            for(int j = 0; j < hosts.length; j++) {
                if(cpus.length == 1)
                    numCPUs = cpus[0];
                else
                    numCPUs = cpus[j];

                // User don't want to reconfigure this system.
                if(numCPUs == 0)
                    continue;

                try {
                    // We first turn on all cpus, then turn off enough of them
                    // to get the required number
                    Command cmd = new Command(Config.BIN_DIR + "fastsu",
                            "/usr/sbin/psradm", "-a", "-n");
                    logger.config("Turning on all cpus on " + hosts[j]);
                    cmds.execute(hosts[j], cmd, null);

                    cmd = new Command("/usr/sbin/psrinfo");
                    cmd.setStreamHandling(Command.STDOUT, Command.CAPTURE);
                    logger.fine("Getting cpus");
                    CommandHandle handle = cmds.execute(hosts[j], cmd, null);
                    byte[] buffer = handle.fetchOutput(Command.STDOUT);

                    if (buffer != null) {
                        StringTokenizer t =
                                new StringTokenizer(new String(buffer), "\n");

                        ArrayList<Integer> cpuList = new ArrayList<Integer>();
                        boolean isMultiCore = false;

                        while (t.hasMoreTokens()) {
                            String line = t.nextToken();
                            // build list of cpus
                            Integer cpuId = Integer.valueOf((
                                    new StringTokenizer(line)).nextToken().
                                    trim());
                            if((isMultiCore == false) &&
                                    (cpuId.intValue() > 511))
                                isMultiCore = true;
                            cpuList.add(cpuId);
                        }
                        logger.info("Total number of CPUs is " +
                                cpuList.size()/(isMultiCore ? 2 : 1));

                        // The index gets changed when you remove elements
                        // Remove number of CPUs configured to be used for this
                        // server
                        for(int k = 0; k < numCPUs; k++) {
                            if(isMultiCore) {
                                Integer cpuId = new Integer(
                                        (cpuList.get(0)).intValue() + 512);
                                cpuList.remove(cpuId);
                            }
                            cpuList.remove(0);
                        }

                        logger.info("Number of CPUs turned off is " +
                                cpuList.size()/(isMultiCore ? 2 : 1));

                        // The remaining CPUs in the list have to be turned off.

                        if (cpuList.size() > 0) {
                            ArrayList<String> offlineCmd = new ArrayList<String>();
                            offlineCmd.add(Config.BIN_DIR + "fastsu");
                            offlineCmd.add("/usr/sbin/psradm");
                            offlineCmd.add("-f");

                            for(int k = 0; k < cpuList.size(); k++)
                                offlineCmd.add(cpuList.get(k).toString());

                            logger.info("Off-lining CPUs with command: " +
                                    offlineCmd);
                            cmd = new Command(offlineCmd);
                            cmds.execute(hosts[j], cmd, null);
                        }
                    } else {
                        logger.severe("Could not set CPUs on server " +
                                hosts[j]);
                    }
                } catch (Exception ie) {
                    logger.log(Level.SEVERE, "Failed to set Server Config.", ie);
                    return(false);
                }
            }
        }
        return(true);
    }

    /**
     * Get system logs for benchmark duration.
     * This method captures the relevant portion of var/adm/messages
     * to the system report file for the benchmark run.

     * @param startTime of benchmark run
     * @param endTime of benchmark run
     */
    public void report(long startTime, long endTime) {

        String sysfile = run.getOutDir() + "system.report";
        PrintStream syslog = null;
        DateFormat df = DateFormat.getDateTimeInstance(
                            DateFormat.MEDIUM, DateFormat.LONG, Locale.US);
        String start = df.format(new Date(startTime));
        String end = df.format(new Date(endTime));

        String startMon = start.substring(0, 3);
        int ind = start.indexOf(',');
        String startDay = start.substring(4, ind);
        ind = ind + 7; // skip over ' 1999 ' to get to time
        String stime = start.substring(ind, start.indexOf(' ', ind));
        logger.fine("Run started Month = " + startMon +
                " Day = " + startDay + " Time = " + stime);

        String endMon = end.substring(0, 3);
        ind = end.indexOf(',');
        String endDay = end.substring(4, ind);
        ind = ind + 7; // skip over ' 1999 ' to get to time
        String etime = end.substring(ind, end.indexOf(' ', ind));
        logger.fine("Run ended Month = " + endMon
                + " Day = " + endDay + " Time = " + etime);

        // Now, get /var/adm/messages and look for messages between
        // start and end
        CommandHandle handle;
        Command c = new Command("messages", "\"" +
                startMon + " " + startDay + " " + stime + "\"",
                "\""  + endMon + " " + endDay + " " + etime + "\"");
        c.setStreamHandling(Command.STDOUT, Command.CAPTURE);
        logger.fine("Getting system messages");

        for (ParamRepository.HostConfig hostConfig : hostConfigs) {
            for(String host : hostConfig.hosts) {
                String machineName = cmds.getHostName(host);
                File f = new File(sysfile + "." + machineName);
                f.delete();
                try {
                    syslog = new PrintStream(new FileOutputStream(f));
                    handle = cmds.execute(host, c, null);
                    byte[] messages = handle.fetchOutput(Command.STDOUT);
                    syslog.println(linesep);
                    syslog.println("System messages during run from server " +
                            host);
                    syslog.println("\n");
                    if (messages != null) // Null if no messages.
                        syslog.write(messages);
                    syslog.println("\n");
                } catch (RemoteException e) {
                    Throwable t = e;
                    Throwable cause = t.getCause();
                    while (cause != null) {
                        t = cause;
                        cause = t.getCause();
                    }
                    String message = "Error processing system messages for " +
                                                                    host;
                    // A remote IOException usually means the messages script
                    // is not available for the target OS. We want to log
                    // at a lower level.
                    if (t instanceof IOException)
                        logger.log(Level.FINE, message, t);
                    else
                        logger.log(Level.WARNING, message, t);
                } catch (Exception e) {
                    logger.log(Level.WARNING,
                            "Error collecting system messages from " + host,
                            e);
                }
            }
        }
    }
}
TOP

Related Classes of com.sun.faban.harness.engine.ServerConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.