geom_gate userland utility improvements
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

331 lines
7.0 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 <netdb.h>
  48. #include <syslog.h>
  49. #include <stdarg.h>
  50. #include <libgeom.h>
  51. #include <geom/gate/g_gate.h>
  52. #include "ggate.h"
  53. int g_gate_devfd = -1;
  54. int g_gate_verbose = 0;
  55. void
  56. g_gate_vlog(int priority, const char *message, va_list ap)
  57. {
  58. if (g_gate_verbose) {
  59. const char *prefix;
  60. switch (priority) {
  61. case LOG_ERR:
  62. prefix = "error";
  63. break;
  64. case LOG_WARNING:
  65. prefix = "warning";
  66. break;
  67. case LOG_NOTICE:
  68. prefix = "notice";
  69. break;
  70. case LOG_INFO:
  71. prefix = "info";
  72. break;
  73. case LOG_DEBUG:
  74. prefix = "debug";
  75. break;
  76. default:
  77. prefix = "unknown";
  78. }
  79. printf("%s: ", prefix);
  80. vprintf(message, ap);
  81. printf("\n");
  82. } else {
  83. if (priority != LOG_DEBUG)
  84. vsyslog(priority, message, ap);
  85. }
  86. }
  87. void
  88. g_gate_log(int priority, const char *message, ...)
  89. {
  90. va_list ap;
  91. va_start(ap, message);
  92. g_gate_vlog(priority, message, ap);
  93. va_end(ap);
  94. }
  95. void
  96. g_gate_xvlog(const char *message, va_list ap)
  97. {
  98. g_gate_vlog(LOG_ERR, message, ap);
  99. g_gate_vlog(LOG_ERR, "Exiting.", ap);
  100. exit(EXIT_FAILURE);
  101. }
  102. void
  103. g_gate_xlog(const char *message, ...)
  104. {
  105. va_list ap;
  106. va_start(ap, message);
  107. g_gate_xvlog(message, ap);
  108. /* NOTREACHED */
  109. va_end(ap);
  110. exit(EXIT_FAILURE);
  111. }
  112. off_t
  113. g_gate_mediasize(int fd)
  114. {
  115. off_t mediasize;
  116. struct stat sb;
  117. if (fstat(fd, &sb) < 0)
  118. g_gate_xlog("fstat(): %s.", strerror(errno));
  119. if (S_ISCHR(sb.st_mode)) {
  120. if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) {
  121. g_gate_xlog("Can't get media size: %s.",
  122. strerror(errno));
  123. }
  124. } else if (S_ISREG(sb.st_mode)) {
  125. mediasize = sb.st_size;
  126. } else {
  127. g_gate_xlog("Unsupported file system object.");
  128. }
  129. return (mediasize);
  130. }
  131. size_t
  132. g_gate_sectorsize(int fd)
  133. {
  134. size_t secsize;
  135. struct stat sb;
  136. if (fstat(fd, &sb) < 0)
  137. g_gate_xlog("fstat(): %s.", strerror(errno));
  138. if (S_ISCHR(sb.st_mode)) {
  139. if (ioctl(fd, DIOCGSECTORSIZE, &secsize) < 0) {
  140. g_gate_xlog("Can't get sector size: %s.",
  141. strerror(errno));
  142. }
  143. } else if (S_ISREG(sb.st_mode)) {
  144. secsize = 512;
  145. } else {
  146. g_gate_xlog("Unsupported file system object.");
  147. }
  148. return (secsize);
  149. }
  150. void
  151. g_gate_open_device(void)
  152. {
  153. g_gate_devfd = open("/dev/" G_GATE_CTL_NAME, O_RDWR, 0);
  154. if (g_gate_devfd < 0)
  155. err(EXIT_FAILURE, "open(/dev/%s)", G_GATE_CTL_NAME);
  156. }
  157. void
  158. g_gate_close_device(void)
  159. {
  160. close(g_gate_devfd);
  161. }
  162. void
  163. g_gate_ioctl(unsigned long req, void *data)
  164. {
  165. if (ioctl(g_gate_devfd, req, data) < 0) {
  166. g_gate_xlog("%s: ioctl(/dev/%s): %s.", getprogname(),
  167. G_GATE_CTL_NAME, strerror(errno));
  168. }
  169. }
  170. void
  171. g_gate_destroy(int unit, int force)
  172. {
  173. struct g_gate_ctl_destroy ggio;
  174. ggio.gctl_version = G_GATE_VERSION;
  175. ggio.gctl_unit = unit;
  176. ggio.gctl_force = force;
  177. g_gate_ioctl(G_GATE_CMD_DESTROY, &ggio);
  178. }
  179. int
  180. g_gate_openflags(unsigned ggflags)
  181. {
  182. if ((ggflags & G_GATE_FLAG_READONLY) != 0)
  183. return (O_RDONLY);
  184. else if ((ggflags & G_GATE_FLAG_WRITEONLY) != 0)
  185. return (O_WRONLY);
  186. return (O_RDWR);
  187. }
  188. void
  189. g_gate_load_module(void)
  190. {
  191. if (modfind("g_gate") < 0) {
  192. /* Not present in kernel, try loading it. */
  193. if (kldload("geom_gate") < 0 || modfind("g_gate") < 0) {
  194. if (errno != EEXIST) {
  195. errx(EXIT_FAILURE,
  196. "geom_gate module not available!");
  197. }
  198. }
  199. }
  200. }
  201. #ifdef LIBGEOM
  202. static struct gclass *
  203. find_class(struct gmesh *mesh, const char *name)
  204. {
  205. struct gclass *class;
  206. LIST_FOREACH(class, &mesh->lg_class, lg_class) {
  207. if (strcmp(class->lg_name, name) == 0)
  208. return (class);
  209. }
  210. return (NULL);
  211. }
  212. static const char *
  213. get_conf(struct ggeom *gp, const char *name)
  214. {
  215. struct gconfig *conf;
  216. LIST_FOREACH(conf, &gp->lg_config, lg_config) {
  217. if (strcmp(conf->lg_name, name) == 0)
  218. return (conf->lg_val);
  219. }
  220. return (NULL);
  221. }
  222. static void
  223. show_config(struct ggeom *gp, int verbose)
  224. {
  225. struct gprovider *pp;
  226. pp = LIST_FIRST(&gp->lg_provider);
  227. if (pp == NULL)
  228. return;
  229. if (!verbose) {
  230. printf("%s\n", pp->lg_name);
  231. return;
  232. }
  233. printf(" NAME: %s\n", pp->lg_name);
  234. printf(" info: %s\n", get_conf(gp, "info"));
  235. printf(" access: %s\n", get_conf(gp, "access"));
  236. printf(" timeout: %s\n", get_conf(gp, "timeout"));
  237. printf("queue_count: %s\n", get_conf(gp, "queue_count"));
  238. printf(" queue_size: %s\n", get_conf(gp, "queue_size"));
  239. printf(" references: %s\n", get_conf(gp, "ref"));
  240. printf(" mediasize: %jd\n", pp->lg_mediasize);
  241. printf(" sectorsize: %u\n", pp->lg_sectorsize);
  242. printf(" mode: %s\n", pp->lg_mode);
  243. printf("\n");
  244. }
  245. void
  246. g_gate_list(int unit, int verbose)
  247. {
  248. struct gmesh mesh;
  249. struct gclass *class;
  250. struct ggeom *gp;
  251. char name[64];
  252. int error;
  253. error = geom_gettree(&mesh);
  254. if (error != 0)
  255. exit(EXIT_FAILURE);
  256. class = find_class(&mesh, G_GATE_CLASS_NAME);
  257. if (class == NULL) {
  258. geom_deletetree(&mesh);
  259. exit(EXIT_SUCCESS);
  260. }
  261. if (unit >= 0) {
  262. snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
  263. unit);
  264. }
  265. LIST_FOREACH(gp, &class->lg_geom, lg_geom) {
  266. if (unit != -1 && strcmp(gp->lg_name, name) != 0)
  267. continue;
  268. show_config(gp, verbose);
  269. }
  270. geom_deletetree(&mesh);
  271. exit(EXIT_SUCCESS);
  272. }
  273. #endif /* LIBGEOM */
  274. in_addr_t
  275. g_gate_str2ip(const char *str)
  276. {
  277. struct hostent *hp;
  278. in_addr_t ip;
  279. ip = inet_addr(str);
  280. if (ip != INADDR_NONE) {
  281. /* It is a valid IP address. */
  282. return (ip);
  283. }
  284. /* Check if it is a valid host name. */
  285. hp = gethostbyname(str);
  286. if (hp == NULL)
  287. return (INADDR_NONE);
  288. return (((struct in_addr *)(void *)hp->h_addr)->s_addr);
  289. }