openGFS , a kind of file system.

源代码在线查看: gserv.c

软件大小: 82 K
上传用户: luoxuetian
关键词: openGFS system kind file
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				 *				 *    Copyright 2000-2001 Sistina Software, Inc.				 *    Portions Copyright 2001 The OpenGFS Project				 *				 *    This is free software released under the GNU General Public License.				 *    There is no warranty for this software.  See the file COPYING for				 *    details.				 *				 *    See the file AUTHORS for a list of contributors.				 *				 */								/*				 * This is a user level interface for setting up and configuring the				 * kgnbd kernel server.  Soon it will also be able to interface the 				 * gnbdd user level server.				 */								/*				 * AUDIT: 				 *	- Fixed multiple local possible buffer overruns, nothing serious				 *	- Fixed malloc checks				 */								#include 				#include 				#include 				#include 				#include 				#include 				#include 				#include 				#include 				#include 				#include 								int kernel_server;				int fd;				int read_fd;				int message_flag = 1;								#define printm(fmt, args...)\				{\					if(message_flag != 0) \						fprintf(stderr, "gserv: " fmt, ##args); \				}												size_t gserv_read(void *buf, size_t count)				{					if (kernel_server)						return read(fd, buf, count);					return read(read_fd, buf, count);				}								size_t gserv_write(const void *buf, size_t count)				{					return write(fd, buf, count);				}								int get_fd(int flags)				{					fd = open("/proc/kgnbd", flags);					if (fd < 0 && errno != ENOENT) {						fprintf(stderr, "could not open /proc/kgnbd: %s\n",							strerror(errno));						return -1;					}					if (fd >= 0) {						kernel_server = 1;						return 0;					}					if ((flags & O_ACCMODE) == O_WRONLY) {						fd = open("/dev/gnbd_rdpipe", flags);						if (fd < 0) {							fprintf(stderr,								"couldn't connect to gnbd_rdpipe: %s\n",								strerror(errno));							return -1;						}					}					if ((flags & O_ACCMODE) == O_RDONLY) {						read_fd = open("/dev/gnbd_wrpipe", flags);						if (read_fd < 0) {							fprintf(stderr,								"couldn't connect to gnbd_wrpipe: %s\n",								strerror(errno));							return -1;						}					}					kernel_server = 0;					return 0;				}												int servcreate(char *filename, char *pathname)				{					int len = strlen(filename) + strlen(pathname) + 9;					char *buf = (char *) malloc(len * sizeof(char));					if(buf == NULL)						exit(1);					snprintf(buf, len, "create/%s/%s", filename, pathname);					if (write(fd, buf, len) != len) {						fprintf(stderr, "create request failed: %s\n",							strerror(errno));						free(buf);						return 1;					}					free(buf);					printm("created GNBD %s serving file %s\n", filename, pathname);					return 0;				}								int servremove(char *filename)				{					int len = strlen(filename) + 8;					char *buf = (char *) malloc(len * sizeof(char));					if(!buf)						exit(1);					snprintf(buf, len, "remove/%s", filename);					if (gserv_write(buf, len) != len) {						fprintf(stderr, "remove request failed: %s\n",							strerror(errno));						free(buf);						return 1;					}					free(buf);					printm("removed GNBD %s\n", filename);					return 0;				}								int removeall(void)				{					int bytes, total = 0;					char *serv, *bufptr;					char buf[4096];					while ((bytes = gserv_read(buf + total, 4096 - total)) != 0) {						if (bytes < 0 && errno != -EINTR) {							fprintf(stderr, "remove request failed: %s\n",								strerror(errno));							return 1;						}						total += bytes;					}					if (total < 4096)						buf[total] = 0;					else						buf[total] = 0;					bufptr = buf;					while ((serv = strchr(bufptr, '/')) != NULL) {						serv++;						bufptr = strchr(serv, '/');						*bufptr++ = 0;						bufptr = strstr(bufptr, "blocksize");						servremove(serv);						if (bufptr == NULL) {							fprintf(stderr,								"incorrectly formatted serverlist\n");							return 1;						}					}					return 0;				}								int portstop(void)				{					char *buf = "portstop";					if (gserv_write(buf, 9) != 9) {						fprintf(stderr, "stop kgnbd_portd request failed: %s\n",							strerror(errno));						return 1;					}					printm("kgnbd_portd stopped\n");					return 0;				}								int portstart(unsigned int port)				{					int len;					char buf[16];					if (port != 0)						snprintf(buf, 16, "portstart/%u", port);					else						snprintf(buf, 16, "portstart");					len = strlen(buf);					if (gserv_write(buf, len + 1) != len + 1) {						fprintf(stderr, "start kgnbd_portd request failed: %s\n",							strerror(errno));						return 1;					}					printm("kgnbd_portd started\n");					return 0;				}								int list(void)				{					int n;					int bytes = 0;					char *serv;					char buf[4096];					char *bufptr = buf;					while ((n = gserv_read(buf + bytes, 4096 - bytes)) != 0) {						if (n < 0 && errno != -EINTR) {							fprintf(stderr, "list request failed: %s\n",								strerror(errno));							return 1;						}						bytes += n;					}					if (bytes < 4096)						buf[bytes] = 0;					else						buf[4095] = 0;					bufptr = strchr(buf, '\n');					*bufptr = 0;					bufptr = bufptr + 2;					printf("%s\n\n", buf);					if (strncmp(bufptr, "no", 2) == 0) {						serv = strchr(bufptr, '\n');						*serv = 0;						printf("%s\n", bufptr);						return 0;					}					while ((serv = strstr(bufptr, "Server")) != NULL) {						bufptr = strchr(serv, '/');						*bufptr++ = ' ';						bufptr = strchr(bufptr, '/');						*bufptr++ = ' ';						bufptr = strstr(serv, "\n       pid");						*bufptr++ = 0;						printf("%s\n\n", serv);					}					return 0;				}								int usage(void)				{					printf("Usage:\n\n");									printf("gserv [-q]  \n");					printf					    ("    Create and export new GNBD from named device or file.\n\n");									printf("gserv [-q] -r \n");					printf("    Remove (un-export) named GNBD.\n\n");									printf("gserv -l\n");					printf("    List exported GNBD's and kgnbd_portd server.\n\n");									printf("gserv [-q] -p []\n");					printf("    Start the kgnbd_portd server (default 14243).\n\n");									printf("gserv [-q] -s\n");					printf("    Stop the current kgnbd_portd server.\n\n");									printf("gserv -h\n");					printf("    Print help.\n\n");									printf("-q toggles gserv to quiet mode, so it does not print on "					       "success\n\n");								#if 0					printf("Create an new kgnbd server for a file or block device\n"					       "   gserv  \n");					printf("Remove a kgnbd server\n" "   gserv -r \n");					printf("List the kgnbd and kgnbd_portd servers currently running\n"					       "   gserv -l\n");					printf					    ("Start up the kgnbd_portd server (if no port is specified, the default is 14243)\n"					     "   gserv -p []\n");					printf("Stop the current kgnbd_portd server\n" "   gserv -s\n");					printf("Print this message\n" "   gserv -h\n\n");				#endif					return 1;				}												int main(int argc, char **argv)				{					int c;					int i;					char *tailptr;					unsigned long int port = 0;					if (argc < 2) {						return usage();					}				loop:					c = getopt(argc, argv, "qlrpsh");					switch (c) {					case 'q':						message_flag = 0;						goto loop;					case -1:						if (argc - optind != 2)							return usage();						if (get_fd(O_WRONLY) < 0)							return 1;						return servcreate(argv[optind], argv[optind + 1]);					case 'l':						if (optind != argc) {							fprintf(stderr,								"unnecessary argument after list request: %s\n\n",								argv[optind]);							return usage();						}						if (get_fd(O_RDONLY) < 0)							return 1;						return list();					case 'r':						if (get_fd(O_RDWR) < 0)							return 1;						if (optind == argc)							return removeall();						for (i = optind; i < argc; i++)							if (servremove(argv[i]) != 0) {								fprintf(stderr, "couldn't remove %s: %s\n",									argv[i], strerror(errno));								return 1;							}						return 0;					case 'p':						if (argc != optind) {							fprintf(stderr,								"unnecessary argument to kgnbd_portd request\n\n");							return usage();						}						/*						   if (argc - optind > 1){						   fprintf(stderr, "unnecessary argument after port number\n\n");						   return usage();						   }						 */						if (argc == optind)							port = 0;						else {							port = strtoul(argv[optind], &tailptr, 0);							if (port  65536) {								fprintf(stderr,									"invalid port number: %s\n\n",									argv[optind]);								return usage();							}						}						if (get_fd(O_WRONLY) < 0)							return 1;						return portstart((unsigned int) port);					case 's':						if (optind != argc) {							fprintf(stderr,								"unnecessary argument to stop kgnbd_portd "								"request\n\n");							return usage();						}						if (get_fd(O_WRONLY) < 0)							return 1;						return portstop();					case '?':						if (isprint(optopt))							fprintf(stderr, "Unknown option: -%c\n\n", optopt);						else							fprintf(stderr, "Unknown option\n\n");						return usage();					case 'h':					default:						return usage();					}				}							

相关资源