geom_gate userland utility improvements
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

336 linhas
7.3 KiB

  1. /*-
  2. * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
  18. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. * SUCH DAMAGE.
  25. *
  26. * $FreeBSD$
  27. */
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <unistd.h>
  31. #include <fcntl.h>
  32. #include <sys/param.h>
  33. #include <sys/disk.h>
  34. #include <sys/stat.h>
  35. #include <sys/endian.h>
  36. #include <sys/socket.h>
  37. #include <sys/linker.h>
  38. #include <sys/module.h>
  39. #include <netinet/in.h>
  40. #include <arpa/inet.h>
  41. #include <signal.h>
  42. #include <err.h>
  43. #include <errno.h>
  44. #include <string.h>
  45. #include <strings.h>
  46. #include <libgen.h>
  47. #include <libutil.h>
  48. #include <netdb.h>
  49. #include <syslog.h>
  50. #include <stdarg.h>
  51. #include <stdint.h>
  52. #include <libgeom.h>
  53. #include <geom/gate/g_gate.h>
  54. #include "ggate.h"
  55. int g_gate_devfd = -1;
  56. int g_gate_verbose = 0;
  57. void
  58. g_gate_vlog(int priority, const char *message, va_list ap)
  59. {
  60. if (g_gate_verbose) {
  61. const char *prefix;
  62. switch (priority) {
  63. case LOG_ERR:
  64. prefix = "error";
  65. break;
  66. case LOG_WARNING:
  67. prefix = "warning";
  68. break;
  69. case LOG_NOTICE:
  70. prefix = "notice";
  71. break;
  72. case LOG_INFO:
  73. prefix = "info";
  74. break;
  75. case LOG_DEBUG:
  76. prefix = "debug";
  77. break;
  78. default:
  79. prefix = "unknown";
  80. }
  81. printf("%s: ", prefix);
  82. vprintf(message, ap);
  83. printf("\n");
  84. } else {
  85. if (priority != LOG_DEBUG)
  86. vsyslog(priority, message, ap);
  87. }
  88. }
  89. void
  90. g_gate_log(int priority, const char *message, ...)
  91. {
  92. va_list ap;
  93. va_start(ap, message);
  94. g_gate_vlog(priority, message, ap);
  95. va_end(ap);
  96. }
  97. void
  98. g_gate_xvlog(const char *message, va_list ap)
  99. {
  100. g_gate_vlog(LOG_ERR, message, ap);
  101. g_gate_vlog(LOG_ERR, "Exiting.", ap);
  102. exit(EXIT_FAILURE);
  103. }
  104. void
  105. g_gate_xlog(const char *message, ...)
  106. {
  107. va_list ap;
  108. va_start(ap, message);
  109. g_gate_xvlog(message, ap);
  110. /* NOTREACHED */
  111. va_end(ap);
  112. exit(EXIT_FAILURE);
  113. }
  114. off_t
  115. g_gate_mediasize(int fd)
  116. {
  117. off_t mediasize;
  118. struct stat sb;
  119. if (fstat(fd, &sb) == -1)
  120. g_gate_xlog("fstat(): %s.", strerror(errno));
  121. if (S_ISCHR(sb.st_mode)) {
  122. if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) == -1) {
  123. g_gate_xlog("Can't get media size: %s.",
  124. strerror(errno));
  125. }
  126. } else if (S_ISREG(sb.st_mode)) {
  127. mediasize = sb.st_size;
  128. } else {
  129. g_gate_xlog("Unsupported file system object.");
  130. }
  131. return (mediasize);
  132. }
  133. size_t
  134. g_gate_sectorsize(int fd)
  135. {
  136. size_t secsize;
  137. struct stat sb;
  138. if (fstat(fd, &sb) == -1)
  139. g_gate_xlog("fstat(): %s.", strerror(errno));
  140. if (S_ISCHR(sb.st_mode)) {
  141. if (ioctl(fd, DIOCGSECTORSIZE, &secsize) == -1) {
  142. g_gate_xlog("Can't get sector size: %s.",
  143. strerror(errno));
  144. }
  145. } else if (S_ISREG(sb.st_mode)) {
  146. secsize = 512;
  147. } else {
  148. g_gate_xlog("Unsupported file system object.");
  149. }
  150. return (secsize);
  151. }
  152. void
  153. g_gate_open_device(void)
  154. {
  155. g_gate_devfd = open("/dev/" G_GATE_CTL_NAME, O_RDWR, 0);
  156. if (g_gate_devfd == -1)
  157. err(EXIT_FAILURE, "open(/dev/%s)", G_GATE_CTL_NAME);
  158. }
  159. void
  160. g_gate_close_device(void)
  161. {
  162. close(g_gate_devfd);
  163. }
  164. void
  165. g_gate_ioctl(unsigned long req, void *data)
  166. {
  167. if (ioctl(g_gate_devfd, req, data) == -1) {
  168. g_gate_xlog("%s: ioctl(/dev/%s): %s.", getprogname(),
  169. G_GATE_CTL_NAME, strerror(errno));
  170. }
  171. }
  172. void
  173. g_gate_destroy(int unit, int force)
  174. {
  175. struct g_gate_ctl_destroy ggio;
  176. ggio.gctl_version = G_GATE_VERSION;
  177. ggio.gctl_unit = unit;
  178. ggio.gctl_force = force;
  179. g_gate_ioctl(G_GATE_CMD_DESTROY, &ggio);
  180. }
  181. int
  182. g_gate_openflags(unsigned ggflags)
  183. {
  184. if ((ggflags & G_GATE_FLAG_READONLY) != 0)
  185. return (O_RDONLY);
  186. else if ((ggflags & G_GATE_FLAG_WRITEONLY) != 0)
  187. return (O_WRONLY);
  188. return (O_RDWR);
  189. }
  190. void
  191. g_gate_load_module(void)
  192. {
  193. if (modfind("g_gate") == -1) {
  194. /* Not present in kernel, try loading it. */
  195. if (kldload("geom_gate") == -1 || modfind("g_gate") == -1) {
  196. if (errno != EEXIST) {
  197. errx(EXIT_FAILURE,
  198. "geom_gate module not available!");
  199. }
  200. }
  201. }
  202. }
  203. #ifdef LIBGEOM
  204. static struct gclass *
  205. find_class(struct gmesh *mesh, const char *name)
  206. {
  207. struct gclass *class;
  208. LIST_FOREACH(class, &mesh->lg_class, lg_class) {
  209. if (strcmp(class->lg_name, name) == 0)
  210. return (class);
  211. }
  212. return (NULL);
  213. }
  214. static const char *
  215. get_conf(struct ggeom *gp, const char *name)
  216. {
  217. struct gconfig *conf;
  218. LIST_FOREACH(conf, &gp->lg_config, lg_config) {
  219. if (strcmp(conf->lg_name, name) == 0)
  220. return (conf->lg_val);
  221. }
  222. return (NULL);
  223. }
  224. static void
  225. show_config(struct ggeom *gp, int verbose)
  226. {
  227. struct gprovider *pp;
  228. char buf[5];
  229. pp = LIST_FIRST(&gp->lg_provider);
  230. if (pp == NULL)
  231. return;
  232. if (!verbose) {
  233. printf("%s\n", pp->lg_name);
  234. return;
  235. }
  236. printf(" NAME: %s\n", pp->lg_name);
  237. printf(" info: %s\n", get_conf(gp, "info"));
  238. printf(" access: %s\n", get_conf(gp, "access"));
  239. printf(" timeout: %s\n", get_conf(gp, "timeout"));
  240. printf("queue_count: %s\n", get_conf(gp, "queue_count"));
  241. printf(" queue_size: %s\n", get_conf(gp, "queue_size"));
  242. printf(" references: %s\n", get_conf(gp, "ref"));
  243. humanize_number(buf, sizeof(buf), (int64_t)pp->lg_mediasize, "",
  244. HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  245. printf(" mediasize: %jd (%s)\n", (intmax_t)pp->lg_mediasize, buf);
  246. printf(" sectorsize: %u\n", pp->lg_sectorsize);
  247. printf(" mode: %s\n", pp->lg_mode);
  248. printf("\n");
  249. }
  250. void
  251. g_gate_list(int unit, int verbose)
  252. {
  253. struct gmesh mesh;
  254. struct gclass *class;
  255. struct ggeom *gp;
  256. char name[64];
  257. int error;
  258. error = geom_gettree(&mesh);
  259. if (error != 0)
  260. exit(EXIT_FAILURE);
  261. class = find_class(&mesh, G_GATE_CLASS_NAME);
  262. if (class == NULL) {
  263. geom_deletetree(&mesh);
  264. exit(EXIT_SUCCESS);
  265. }
  266. if (unit >= 0) {
  267. snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
  268. unit);
  269. }
  270. LIST_FOREACH(gp, &class->lg_geom, lg_geom) {
  271. if (unit != -1 && strcmp(gp->lg_name, name) != 0)
  272. continue;
  273. show_config(gp, verbose);
  274. }
  275. geom_deletetree(&mesh);
  276. exit(EXIT_SUCCESS);
  277. }
  278. #endif /* LIBGEOM */
  279. in_addr_t
  280. g_gate_str2ip(const char *str)
  281. {
  282. struct hostent *hp;
  283. in_addr_t ip;
  284. ip = inet_addr(str);
  285. if (ip != INADDR_NONE) {
  286. /* It is a valid IP address. */
  287. return (ip);
  288. }
  289. /* Check if it is a valid host name. */
  290. hp = gethostbyname(str);
  291. if (hp == NULL)
  292. return (INADDR_NONE);
  293. return (((struct in_addr *)(void *)hp->h_addr)->s_addr);
  294. }