Docs GODI Archive
Projects Blog Knowledge

Look up function:

(e.g. "List.find" or "keysym")
More options


/* $Id: pfs_nn_internal.x 329 2010-12-28 23:52:54Z gerd $ -*- c -*- */

Internal interfaces used by the namenodes

#include "pfs_types.x"



The election happens at cluster startup. The goal is to determine the coordinator. Participants are all namenodes.

program Elect {
    version V1 {


	void null(void) = 0;


	ann_result announce(announcement) = 1;
At cluster start the namenodes start calling the announce RPC of all other namenodes - until they get a reply from each, or until the end of the startup period is reached.

If received within the startup period, the response is ANN_ACCEPT if the announcement is better than the server to which it is sent. Otherwise it is ANN_REJECT. If received after startup, the response is always ANN_REJECT, and the sender must not start up. The response is ANN_SELF if the namenode instance sends the announcement to itself.

As all namenodes call announce of all other namenodes, the question is whether there is a winner. If we assume there is a total ordering between the announcements, there is a best announcement if no two namenodes emit equal announcements. So given the announcements are all distinct, there is a winner.


	void set_coordinator(longstring, longstring, longstring) = 2;
When the end of the startup period is reached, one of the name nodes sends set_coordinator to all other nodes, and becomes the coordinator. The coordinator must be eligible by all other nodes that actually respond. Also, the coordinator must have a highest revision number, and among all nodes with the highest revision number, the coordinator has the lowest rank.

The first arg is the "host:port" name of the coordinator. (Instead of the host name this string can also name the coordinator by IP address if this is the preferred method of referencing it.)

The second arg is the clustername.

The third arg is the revision identifier.

There is right now no provision for the case that the coordinator crashes - no other node is then automatically elected. Best is to restart everything then.

    } = 1;
} = 0x8000f001;


This RPC program is activated on the non-coordinator namenodes. It is called by the coordinator to push updates of the database.

program Nameslave {
    version V1 {
	/* This is what the non-coordinators implement */


	void null(void) = 0;


	void begin_transaction(longstring, longstring) = 1;
Begin a transaction: clustername, expected_rev. The 2nd arg is the expected revision string


	bool prepare_commit(void) = 2;
Result is true if the name database could be updated.


	void commit(void) = 3;
The response of commit is the ACK in the extended 2-phase commit protocol

	/* void abort(void) = 4; */

Note that the names of the following RPCs correspond to function names in Nn_db:


	void set_ds_cache(ds_info_list) = 5;
set_ds_cache(l): calls Nn_db.ds_cache_init(`Datastores l)


	void push_inode_ins(hyper, inodeinfo) = 7;
push_inode_ins(inode, ii)


	void push_inode_upd(hyper, inodeinfo) = 8;
push_inode_upd(inode, ii)


	void push_inode_upd_time(hyper, time_opt, time_opt) = 18;
push_inode_upd_time(inode, mtime, ctime)


	void push_inode_del(hyper) = 9;


	void push_blockalloc_upd(int, hyper, longstring) = 10;


	void push_datastore_upd(int, longstring, hyper, bool) = 11;
push_upd_datastore(id,identity,size,enabled): Updates the datastore table. If the record is new, it is added.

The blockalloc table is updated, too: For new stores, the rows are added. If the size of the existing store is increased, further rows are added.

It is an error to decrease the size.


	void push_datastore_del(int) = 12;
Deletes the datastore with this ID and all rows referencing it


	void push_revision_upd(longstring) = 13;
Sets the revision id in the db


	void push_inodeblocks_ins(hyper, blocklist) = 14;
push_inodeblocks_ins(inode, bl)


	void push_inodeblocks_del(hyper, hyper, hyper) = 15;
push_inodeblocks_del(inode, blkidx, len)


	void push_names_ins(hyper, longstring, hyper) = 16;
push_names_ins(dir_inode, path, inode)


	void push_names_del(hyper, longstring) = 17;

    } = 1;
} = 0x8000f002;


program Monitor {
    version V1 {


	void null(void) = 0;


	void start(void) = 1;
Starts the monitor: First, the state is loaded from the db. Second, all known datanodes are discovered and enabled. Third, the newsfeed for monitoring results is started. Fourth, the Dn_admin interface is enabled.

    } = 1;
} = 0x8000f003;



The inodecache calls the program Request_notifications which is available in the coordinator. Once something is to report, the coordinator calls the inodecache back. The callback is defined by the program Notifications.

program Request_notifications {
    /* Request_notifications is available on the coordinator */

    version V1 {


	void null(void) = 0;


	bool on_inode_update(hyper, hyper, longstring) = 1;
on_inode_update(inode, exptime, socket): requests to be notified when the inode changes or is deleted. Changes cover metadata and data changes. exptime is the point in time when the notification will expire. The socket is either an Internet socket in "host:port" syntax or the path of a Unix Domain socket. The notification will be that the RPC call Notifications.V1.inode_update is invoked.

on_inode_update returns true when the request is successful.

    } = 1;
} = 0x8000f004;


program Notifications {
    version V1 {


	void null(void) = 0;


	void inode_update(hyper, bool) = 1;
inode_update(inode, expires): If expires is true, this call just indicates that the notification request ends. If it is false, the inode has been changed or is deleted.

It is allowed that this RPC is called more often than necessary.

Implementations of this call must be fast! If a transaction changes an inode, the commit cannot be finished before this call is responded.

    } = 1;
} = 0x8000f005;


This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml