1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2013 Damian Bogel. All rights reserved.
14 */
15
16 #include <libfsd.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 /*
21 * Examples of usage:
22 * fsdadm -m /mnt -c 15 -l 1 200 15% read less 1 to 200 for /mnt
23 * fsdadm -n -c 50 -l 1 10 50% read less of 1 to 10ms for every new mount
24 * fsdadm -m /mnt -x clear all disturbances for /mnt
25 * fsdadm -n -x clear all disturbances for every new mount
26 */
27
28 #define READ_LESS 0
29 #define OPS_NUM 1
30
31 int clear;
32 int disable;
33 int enable;
34 int newmount;
35 int options[OPS_NUM];
36
37 int
38 main(int argc, char *argv[])
39 {
40 extern char *optarg;
41 extern int optind;
42
43 char *mnt = NULL;
44 int fd;
45 int opt;
46 int error;
47 fsd_stat_t stat;
48
49 while ((opt = getopt(argc, argv, "edm:c:l:xn")) != -1)
50 switch (opt) {
51 case 'e':
52 enable = 1;
53 break;
54
55 case 'd':
56 disable = 1;
57 break;
58
59 case 'c':
60 stat.fsds_read_less_chance = atoi(optarg);
61 break;
62
63 case 'm':
64 mnt = optarg;
65 break;
66
67 case 'l':
68 options[READ_LESS] = 1;
69 if (optind > argc - 1) {
70 (void) fprintf(stderr,
71 "Error: -l requires two arguments\n");
72 return (1);
73 }
74 stat.fsds_read_less_r[0] = atoi(argv[optind-1]);
75 stat.fsds_read_less_r[1] = atoi(argv[optind]);
76 break;
77
78 case 'x':
79 clear = 1;
80 break;
81
82 case 'n':
83 newmount = 1;
84 break;
85
86 case '?':
87 (void) fprintf(stderr,
88 "Error: Unrecognized option: "
89 "-%c\n", optopt);
90 return (1);
91 }
92
93 fd = fsd_open();
94 if (fd == -1) {
95 (void) fprintf(stderr, "Error: Cannot open fsd device.\n");
96 return (1);
97 }
98
99 error = 0;
100 if (enable) {
101 if (fsd_enable(fd))
102 error = fsd_errno;
103 } else if (disable) {
104 if (fsd_disable(fd))
105 error = fsd_errno;
106 } else {
107 if (newmount) {
108 if (clear) {
109 if (fsd_newdisturb_off(fd))
110 error = fsd_errno;
111 } else {
112 if (fsd_newdisturb(fd, &stat))
113 error = fsd_errno;
114 }
115 } else {
116 if (clear) {
117 if (fsd_disturb_off(fd, mnt))
118 error = fsd_errno;
119 } else {
120 if (fsd_disturb(fd, mnt, &stat))
121 error = fsd_errno;
122 }
123 }
124 }
125
126 fsd_close(fd);
127 if (error) {
128 (void) fprintf(stderr, "Error: %s\n", fsd_strerr(error));
129 return (1);
130 }
131 return (0);
132 }