⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctop.c

📁 linux/unix下c/s形式的资源监视,客户端负责搜集机器,再传送到服务端.
💻 C
字号:
/*  * Print cluster's top information. * * Copyright (c) 2004, by:      Jian Shen *    All rights reserved.      Peking University, China *                             <shenjian@net.pku.edu.cn> * * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Library General Public License for more details. * */#include "statinfo.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <dirent.h>#include <getopt.h>#include <string.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/select.h>#include <termios.h>#include <signal.h>#include <arpa/inet.h>#include <netdb.h>#include <curses.h>#include <term.h>#include <sys/ioctl.h>static int msg_row;static int msg_column;static int NEED_CLEAR = 0;#define MAXSTR 80/********************************* * screen operation *********************************/void msg_print(const char* str) {	putp(tgoto(cursor_address, msg_column, msg_row));//	putp(clr_eol);//	putp(str);	printf("\r%s", str);}void msg_flush(){	fflush(stdout);}void my_clear_screen(){	putp(clear_screen);	fflush(stdout);}/*********************************  * host operation *********************************/#define MAX_HOSTS 16#define NO_SPACE -1#define FAIL_HOST -2char all_hosts[MAX_HOSTS][20];int VERBOSE = 0;static int compare_host(const void*a, const void* b){	char *p,*q;	p = (char*)a;	q = (char*)b;	return strcmp(p, q);}char* get_host_name(char* host_ip){    long hostname;    struct hostent *hinfo;                       	hostname = inet_addr(host_ip);	hinfo = gethostbyaddr((char *)&hostname, sizeof(long), AF_INET);	if(hinfo != NULL)		return hinfo->h_name;	else		return host_ip;}int get_all_hosts(){	DIR *dp;	struct dirent *dirp;	int count;	if((dp = opendir("/proc/cluster")) == NULL) {		fprintf(stderr, "Failed to open /proc/cluster!\n");		exit(1);	}	count = 0;	while((dirp = readdir(dp)) != NULL) {		if(count >= MAX_HOSTS)			break;		if(strcmp(dirp->d_name, ".") == 0)			continue;		if(strcmp(dirp->d_name, "..") == 0)			continue;		strcpy(all_hosts[count], dirp->d_name);		count ++;	}	closedir(dp);	qsort(all_hosts, count, 20, compare_host);	return count;}#define CHECK_ROW() if(msg_row+3 > wsz.ws_row){msg_flush(); return NO_SPACE;}#define PRINT_ROW(r) do { \	msg_print(buf); \	msg_row += r; \	CHECK_ROW(); \    bzero(buf, MAXSTR); \}while(0)int print_load(system_load_info* sysload, char* hostname){	int i;	struct winsize wsz;	ioctl(STDIN_FILENO, TIOCGWINSZ, (char*)&wsz);		if(VERBOSE == 0) {		char buf[MAXSTR];		sprintf(buf, "%s:\n", get_host_name(hostname));		PRINT_ROW(1);		sprintf(buf, "  load average:%5s,%5s,%5s;  ", 			   sysload->loadavg[0],			   sysload->loadavg[1],			   sysload->loadavg[2]);		double average = 0;		for(i=0; i<sysload->num_of_cpu; i++) {			average += atof(sysload->cpu_util[i]);		}		average = average / sysload->num_of_cpu;		sprintf(buf, "%s  cpu: %5.1f%%;  ", buf, average);		sprintf(buf, "%s  mem:%8dk used,%8dk free.\n\n", buf, 			   sysload->total_mem - sysload->free_mem, 			   sysload->free_mem); 		PRINT_ROW(2);		msg_flush();		NEED_CLEAR = 0;	}else if(VERBOSE == 1) {		char buf[MAXSTR];		sprintf(buf, "%s:\n", get_host_name(hostname));		PRINT_ROW(1);		sprintf(buf, "  load average:%5s,%5s,%5s\n", 			   sysload->loadavg[0],			   sysload->loadavg[1],			   sysload->loadavg[2]);		PRINT_ROW(1);		int LINECNT = 4;		for(i=0; i<sysload->num_of_cpu; i++) {			sprintf(buf, "%s  cpu%d:%5s%% ", buf, i, sysload->cpu_util[i]);			if((i+1) % LINECNT == 0) {				sprintf(buf, "%s\n", buf);				PRINT_ROW(1);			}		}		if(sysload->num_of_cpu % LINECNT != 0) {			sprintf(buf, "%s\n", buf);			PRINT_ROW(1);		}		sprintf(buf, "%s  mem:%8dk av,%8dk used,%8dk free\n\n", buf,				sysload->total_mem, 				sysload->total_mem - sysload->free_mem, 				sysload->free_mem); 		PRINT_ROW(2);		msg_flush();		NEED_CLEAR = 0;	}else if(VERBOSE == 2) {		/* most in detail */		printf("%s:\n", get_host_name(hostname));		printf("  os version: %s %s\n", sysload->sysinfo.sysname, sysload->sysinfo.release);		printf("  load average: %5s, %5s, %5s\n", 			   sysload->loadavg[0],			   sysload->loadavg[1],			   sysload->loadavg[2]);		for(i=0; i<sysload->num_of_cpu; i++) {			printf("  cpu%d (%sMHZ) states: %5s%%\n", i, 				   sysload->cpu_freq[i],				   sysload->cpu_util[i]);		}		printf("  mem: %8dk av, %8dk used, %8dk free\n", 			   sysload->total_mem,			   sysload->total_mem - sysload->free_mem, 			   sysload->free_mem);		printf("\n");	}	return 0;}int print_host_load(char* hostname){	system_load_info sysload;	char filename[100];	int fd;	int rv;	sprintf(filename, "/proc/cluster/%s/top.bin", hostname);	fd = open(filename, O_RDONLY);	if(fd < 0) {		return FAIL_HOST;	}	rv = read(fd, &sysload, sizeof(system_load_info));	if(rv != sizeof(system_load_info)) {		close(fd);		return FAIL_HOST;	}	close(fd);	return print_load(&sysload, hostname);}/* get host's ip address by its alias according to /etc/hosts */char* get_host_ip(const char* hostname){	char* hostIP;	struct hostent * h;	struct in_addr* in;	hostIP = (char*)malloc(20*sizeof(char));	/* get host structure by host name */	h = gethostbyname(hostname);	if(h != NULL) {		in = (struct in_addr*)h->h_addr;		sprintf(hostIP,"%s", inet_ntoa(*in));		return hostIP;			/* caller free */	}else {//		fprintf(stderr, "gethostbyname failed.\n");		return NULL;	}}/************************************ * tty operation ************************************/static struct termios save_termios;static int ttysavefd = -1;static enum {RESET, CBREAK} ttystate = RESET;/* put terminal into a cbreak mode */int tty_cbreak(int fd){	struct termios buf;	if(tcgetattr(fd, &save_termios) < 0)		return -1;	buf = save_termios;	buf.c_lflag &= ~(ECHO | ICANON);	buf.c_cc[VMIN] = 1;			/* 1 byte at a time, no timer */	buf.c_cc[VTIME] = 0;	if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)		return -1;	ttystate = CBREAK;	ttysavefd = fd;	return 0;}/* restore terminal's mode */int tty_reset(int fd){	if(ttystate != CBREAK)		return 0;	if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)		return -1;	ttystate = RESET;		return 0;}void tty_atexit(){	if(ttysavefd >= 0)		tty_reset(ttysavefd);}struct termios* tty_termios(){	return (&save_termios);}/********************************* * signal operation *********************************/static void sig_catch(int signo){	exit(0);}static void sig_winch(int signo){	my_clear_screen();	NEED_CLEAR = 1;}void catch_signals(){	if(signal(SIGINT, sig_catch) == SIG_ERR)		fprintf(stderr, "signal(SIGINT) failed.\n");	if(signal(SIGQUIT, sig_catch) == SIG_ERR)		fprintf(stderr, "signal(SIGQUIT) failed.\n");	if(signal(SIGTERM, sig_catch) == SIG_ERR)		fprintf(stderr, "signal(SIGTERM) failed.\n");	if(signal(SIGWINCH, sig_winch) == SIG_ERR)		fprintf(stderr, "signal(SIGWINCH) failed.\n");}/********************************* * main loop *********************************/void do_key(unsigned c){	switch(c) {	case 'q':		exit(0);	case 'v':		VERBOSE = 1 - VERBOSE;	/* toggle verbose option */		NEED_CLEAR = 1;		break;	}}void read_key(){	long file_flags;	char c;	int rc;	fd_set fs;	FD_ZERO(&fs);	FD_SET(STDIN_FILENO, &fs);	file_flags = fcntl(STDIN_FILENO, F_GETFL);	if(file_flags == -1) file_flags = 0;	fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK | file_flags);	rc = read(STDIN_FILENO, &c, 1);	if (rc > 0) {		fcntl(STDIN_FILENO, F_SETFL, file_flags);		do_key((unsigned)c);	} else {		fcntl(STDIN_FILENO, F_SETFL, file_flags);	}}void init_term(){	setupterm((char *) 0, STDOUT_FILENO, (int *) 0);	putp(clear_screen);//	putp(cursor_invisible);	fflush(stdout);	msg_row = 0;	msg_column = 0;				/* this is always 0 */	NEED_CLEAR = 0;}void reset_term(){/* 	putp(cursor_visible); *//* 	fflush(stdout); */}#define SLEEP_INTERVAL 2void usage(){	printf("usage: ctop [-v] [hostname]\n");}void help(){	printf("\nCluster load monitor like top.\n");	printf("usage:\n");	printf("\tctop [-v] [hostname]\n");	printf("examples:\n");	printf("\tctop\n");	printf("\tctop node1\n");	printf("\tctop -v\n");	printf("\tctop -v node1\n");	printf("\nreport bugs to <shenjian@net.pku.edu.cn>.\n");	printf("\n");}int main(int argc, char* argv[]){	/* deal with options */	int MODE = 0;				/* two modes: non-continous and continuous */	int SHOW_HOST = 0;			/* two kinds: one host and all host */	int next_opt;	char** program = argv;	int argcnt = argc;	char* target;				/* target hostname */	const char* short_options = "hv";	const struct option long_options[] = {		{"help", 0, NULL, 'h'},		{"verbose", 0, NULL, 'v'}	};	do{		next_opt = getopt_long(argc, argv, short_options, long_options, NULL);		argcnt -= 1;		switch(next_opt) {		case 'h' :				/* -h or --help */			help();			exit(1);		case '?' :				/* invalid option */			usage();			exit(1);		case 'v':				/* -v or --verbose */			MODE = 1;			program += 1;			break;		case ':' :				/* missing parameters */			usage();			exit(1);		case -1 :				/* end of option list */			break;		default:			printf("Something wrong with getopt_long.\n");			exit(1);		}	}while(next_opt != -1);	program += 1;	if(argcnt == 0) {		SHOW_HOST = 0;	}else if(argcnt == 1) {		SHOW_HOST = 1;	}else {		usage();		exit(1);	}	int num_of_hosts;	int i;	if(SHOW_HOST == 1) {		target = get_host_ip(program[0]);		if(target == NULL) {			fprintf(stderr, "Who is \"%s\"?\n", program[0]);			exit(1);		}	}	if(MODE == 1) {		VERBOSE = 2;		if(SHOW_HOST == 0) {			/* show all host */			num_of_hosts = get_all_hosts();			for(i=0; i<num_of_hosts; i++)				print_host_load(all_hosts[i]);		}else {			/* show only one host */			print_host_load(target);		}	}else {		/* test: terminal is stdin */		if(isatty(STDIN_FILENO) == 0) {			fprintf(stderr, "standard input is not a terminal device\n");			return -1;		}		/* register exit functions */		if(atexit(reset_term) != 0) {			fprintf(stderr, "atexit failed\n");			return -1;		}		if(atexit(tty_atexit) != 0) {			fprintf(stderr, "atexit failed\n");			return -1;		}			catch_signals();		/* initialize terminal */		init_term();		/* set terminal to cbreak mode */		if(tty_cbreak(STDIN_FILENO) < 0) {			fprintf(stderr, "tty_cbreak failed\n");			return -1;		}		if(SHOW_HOST == 0) {			/* get host list */			num_of_hosts = get_all_hosts();			int NEED_RELOAD = 0;			int time_cnt = 0;			for(;;) {				if(time_cnt > 30) {					NEED_RELOAD = 1;				}				if(NEED_RELOAD) {					num_of_hosts = get_all_hosts();					NEED_RELOAD = 0;					NEED_CLEAR = 1;					time_cnt = 0;				}				if(NEED_CLEAR)					my_clear_screen();				msg_row = 0;				for(i=0; i<num_of_hosts; i++) {					int ret = print_host_load(all_hosts[i]); 									if(ret == NO_SPACE)						break;					else if(ret == FAIL_HOST)						NEED_RELOAD = 1;				}				sleep(SLEEP_INTERVAL);				time_cnt += SLEEP_INTERVAL;				read_key();			}		}else {			for(;;) {				if(NEED_CLEAR)					my_clear_screen();				msg_row = 0;				print_host_load(target);				sleep(SLEEP_INTERVAL);				read_key();			}		}		/* reset terminal to original mode */		if(tty_reset(STDIN_FILENO) < 0) {			fprintf(stderr, "tty_reset failed\n");			return -1;		}		reset_term();	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -