org.apache.hadoop.hdfs.server.namenode.ConfigManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hdfs.server.namenode.ConfigManager.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.hdfs.server.namenode;

import org.apache.commons.logging.*;
import org.apache.hadoop.conf.*;

import java.io.*;
import java.util.LinkedList;

/***************************************************
 * Manager FSNamesystem dynamic loadingof configurations.
 ***************************************************/
public class ConfigManager {
    public static final Log LOG = LogFactory.getLog(FSNamesystem.class);

    /** Time to wait between checks of the allocation file */
    public static final long CONFIG_RELOAD_INTERVAL = 300 * 1000;

    /**
     * Time to wait after the allocation has been modified before reloading it
     * (this is done to prevent loading a file that hasn't been fully written).
     */
    public static final long DEFAULT_CONFIG_RELOAD_WAIT = 10 * 1000;

    private FSNamesystem namesys;
    private String whitelistFile; // Path to file that contains whitelist directories

    private long configReloadWait = DEFAULT_CONFIG_RELOAD_WAIT;
    private long lastReloadAttempt; // Last time we tried to reload the pools file
    private long lastSuccessfulReload; // Last time we successfully reloaded pools
    private boolean lastReloadAttemptFailed = false;

    public ConfigManager(FSNamesystem namesys, Configuration conf) {
        this.namesys = namesys;

        // the name of the whitelist file
        this.whitelistFile = conf.get("dfs.namenode.whitelist.file");
        if (whitelistFile == null) {
            LOG.warn("No whitelist file specified in dfs.namenode.whitelist.file."
                    + " The namenode will allow deletion/renaming of any directory.");
        }

        // periodicity of reload of the config file
        long value = conf.getLong("dfs.namenode.config.reload.wait", 0);
        if (value != 0) {
            configReloadWait = value;
        }
    }

    /**
     * Checks to see if the namenode config file is updated on 
     * disk, If so, then read all it contents. At present, only
     * the whitelist config is updated, but we will enahnce this to
     * update all possible namenode configs in future.
     */
    public void reloadConfigIfNecessary() {
        if (whitelistFile == null) {
            return;
        }
        long time = System.currentTimeMillis();
        if (time > lastReloadAttempt + CONFIG_RELOAD_INTERVAL) {
            lastReloadAttempt = time;
            try {
                File file = new File(whitelistFile);
                long lastModified = file.lastModified();
                if (lastModified > lastSuccessfulReload && time > lastModified + configReloadWait) {
                    reloadWhitelist();
                    lastSuccessfulReload = time;
                    lastReloadAttemptFailed = false;
                }
            } catch (Exception e) {
                // Throwing the error further out here won't help - the RPC thread
                // will catch it and report it in a loop. Instead, just log it and
                // hope somebody will notice from the log.
                // We log the error only on the first failure so we don't fill up the
                // server's log with these messages.
                if (!lastReloadAttemptFailed) {
                    LOG.error("Failed to reload whitelist file - " + "will use existing allocations.", e);
                }
                lastReloadAttemptFailed = true;
            }
        }
    }

    /**
     * Removes all the entries currently in neverDeletePaths 
     * and add the new ones specified
     */
    void reloadWhitelist() throws IOException {

        // read the entire whitelist into memory outside the
        // FSNamessytem lock.
        //
        LinkedList<String> paths = new LinkedList<String>();
        FileInputStream fstream = new FileInputStream(whitelistFile);
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        int count = 0;
        while (true) {
            String str = br.readLine();
            if (str == null) {
                break; // end of file
            }
            str = str.trim(); // remove all whitespace from start and end
            if (str.startsWith("#")) {
                continue; // ignore lines with starting with #
            }
            paths.add(str);
            LOG.info("Whitelisted directory [" + count + "] " + str);
            count++;
        }
        in.close();

        // acquire the writelock and insert newly read entries into 
        // the Namenode's configuration.
        namesys.writeLock();
        try {
            namesys.neverDeletePaths.clear();
            for (String s : paths) {
                namesys.neverDeletePaths.add(s);
            }
        } finally {
            namesys.writeUnlock();
        }
    }
}