perfmonger 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +6 -0
- data/.tachikoma.yml +1 -0
- data/.travis.yml +18 -6
- data/Gemfile +1 -3
- data/Guardfile +26 -0
- data/NEWS +21 -0
- data/README.md +8 -9
- data/Rakefile +33 -1
- data/core/Makefile +23 -0
- data/core/build.sh +48 -0
- data/core/perfmonger-player.go +165 -0
- data/core/perfmonger-recorder.go +296 -0
- data/core/perfmonger-summarizer.go +207 -0
- data/core/subsystem/Makefile +3 -0
- data/core/subsystem/perfmonger.go +60 -0
- data/core/subsystem/perfmonger_darwin.go +22 -0
- data/core/subsystem/perfmonger_linux.go +292 -0
- data/core/subsystem/perfmonger_linux_test.go +73 -0
- data/core/subsystem/stat.go +214 -0
- data/core/subsystem/stat_test.go +281 -0
- data/core/subsystem/usage.go +410 -0
- data/core/subsystem/usage_test.go +496 -0
- data/lib/exec/operationBinding.rb.svn-base +59 -0
- data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-player_linux_386 +0 -0
- data/lib/exec/perfmonger-player_linux_amd64 +0 -0
- data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-recorder_linux_386 +0 -0
- data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
- data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-summarizer_linux_386 +0 -0
- data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
- data/lib/exec/perfmonger-summary_linux_386 +0 -0
- data/lib/exec/perfmonger-summary_linux_amd64 +0 -0
- data/lib/perfmonger/cli.rb +8 -3
- data/lib/perfmonger/command/core.rb +62 -0
- data/lib/perfmonger/command/live.rb +39 -0
- data/lib/perfmonger/command/play.rb +56 -0
- data/lib/perfmonger/command/plot.rb +30 -22
- data/lib/perfmonger/command/record.rb +3 -2
- data/lib/perfmonger/command/record_option.rb +40 -59
- data/lib/perfmonger/command/server.rb +7 -2
- data/lib/perfmonger/command/stat.rb +2 -2
- data/lib/perfmonger/command/stat_option.rb +1 -1
- data/lib/perfmonger/command/summary.rb +11 -326
- data/lib/perfmonger/version.rb +1 -3
- data/lib/perfmonger.rb +3 -0
- data/misc/_perfmonger +128 -0
- data/misc/perfmonger-completion.bash +49 -0
- data/perfmonger.gemspec +6 -5
- data/spec/data/busy100.pgr +0 -0
- data/spec/fingerprint_spec.rb +35 -0
- data/spec/live_spec.rb +25 -0
- data/spec/perfmonger_spec.rb +37 -0
- data/spec/play_spec.rb +21 -0
- data/spec/plot_spec.rb +42 -0
- data/spec/record_spec.rb +15 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/stat_spec.rb +15 -0
- data/spec/summary_spec.rb +51 -0
- data/spec/support/aruba.rb +11 -0
- data/wercker.yml +59 -0
- metadata +117 -45
- data/ext/perfmonger/extconf.rb +0 -19
- data/ext/perfmonger/perfmonger.h +0 -58
- data/ext/perfmonger/perfmonger_record.c +0 -754
- data/ext/perfmonger/sysstat/common.c +0 -627
- data/ext/perfmonger/sysstat/common.h +0 -207
- data/ext/perfmonger/sysstat/ioconf.c +0 -515
- data/ext/perfmonger/sysstat/ioconf.h +0 -84
- data/ext/perfmonger/sysstat/iostat.c +0 -1100
- data/ext/perfmonger/sysstat/iostat.h +0 -121
- data/ext/perfmonger/sysstat/libsysstat.h +0 -19
- data/ext/perfmonger/sysstat/mpstat.c +0 -953
- data/ext/perfmonger/sysstat/mpstat.h +0 -79
- data/ext/perfmonger/sysstat/rd_stats.c +0 -2388
- data/ext/perfmonger/sysstat/rd_stats.h +0 -651
- data/ext/perfmonger/sysstat/sysconfig.h +0 -13
- data/test/run-test.sh +0 -39
- data/test/spec/bin_spec.rb +0 -37
- data/test/spec/data/2devices.expected +0 -42
- data/test/spec/data/2devices.output +0 -42
- data/test/spec/spec_helper.rb +0 -20
- data/test/spec/summary_spec.rb +0 -193
- data/test/test-perfmonger.c +0 -145
- data/test/test.h +0 -9
@@ -1,207 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* (C) 2011 Modified by Yuto HAYAMIZU (haya <at> tkl.iis.u-tokyo.ac.jp)
|
3
|
-
*/
|
4
|
-
|
5
|
-
/*
|
6
|
-
* sysstat: System performance tools for Linux
|
7
|
-
* (C) 1999-2010 by Sebastien Godard (sysstat <at> orange.fr)
|
8
|
-
*/
|
9
|
-
|
10
|
-
#ifndef _COMMON_H
|
11
|
-
#define _COMMON_H
|
12
|
-
|
13
|
-
/* Maximum length of sensors device name */
|
14
|
-
#define MAX_SENSORS_DEV_LEN 20
|
15
|
-
|
16
|
-
#include <time.h>
|
17
|
-
#include <sched.h> /* For __CPU_SETSIZE */
|
18
|
-
#include "rd_stats.h"
|
19
|
-
|
20
|
-
|
21
|
-
/*
|
22
|
-
***************************************************************************
|
23
|
-
* Various keywords and constants
|
24
|
-
***************************************************************************
|
25
|
-
*/
|
26
|
-
|
27
|
-
#ifndef FALSE
|
28
|
-
# define FALSE 0
|
29
|
-
#endif
|
30
|
-
|
31
|
-
#ifndef TRUE
|
32
|
-
# define TRUE 1
|
33
|
-
#endif
|
34
|
-
|
35
|
-
#define DISP_HDR 1
|
36
|
-
|
37
|
-
/* Maximum number of CPUs */
|
38
|
-
#ifdef __CPU_SETSIZE
|
39
|
-
#define NR_CPUS __CPU_SETSIZE
|
40
|
-
#else
|
41
|
-
#define NR_CPUS 1024
|
42
|
-
#endif
|
43
|
-
|
44
|
-
/* Maximum number of interrupts */
|
45
|
-
#define NR_IRQS 256
|
46
|
-
|
47
|
-
/* Size of /proc/interrupts line, CPU data excluded */
|
48
|
-
#define INTERRUPTS_LINE 128
|
49
|
-
|
50
|
-
/* Keywords */
|
51
|
-
#define K_ISO "ISO"
|
52
|
-
#define K_ALL "ALL"
|
53
|
-
#define K_UTC "UTC"
|
54
|
-
|
55
|
-
/* Files */
|
56
|
-
#define STAT "/proc/stat"
|
57
|
-
#define UPTIME "/proc/uptime"
|
58
|
-
#define PPARTITIONS "/proc/partitions"
|
59
|
-
#define DISKSTATS "/proc/diskstats"
|
60
|
-
#define INTERRUPTS "/proc/interrupts"
|
61
|
-
#define MEMINFO "/proc/meminfo"
|
62
|
-
#define SYSFS_BLOCK "/sys/block"
|
63
|
-
#define SYSFS_DEVCPU "/sys/devices/system/cpu"
|
64
|
-
#define SYSFS_TIME_IN_STATE "cpufreq/stats/time_in_state"
|
65
|
-
#define S_STAT "stat"
|
66
|
-
#define DEVMAP_DIR "/dev/mapper"
|
67
|
-
#define DEVICES "/proc/devices"
|
68
|
-
|
69
|
-
#define MAX_FILE_LEN 256
|
70
|
-
#define MAX_PF_NAME 1024
|
71
|
-
#define DEFAULT_DEVMAP_MAJOR 253
|
72
|
-
#define MAX_NAME_LEN 72
|
73
|
-
|
74
|
-
#define NR_DISKS 4
|
75
|
-
|
76
|
-
/* Environment variables */
|
77
|
-
#define ENV_TIME_FMT "S_TIME_FORMAT"
|
78
|
-
#define ENV_TIME_DEFTM "S_TIME_DEF_TIME"
|
79
|
-
|
80
|
-
#define DIGITS "0123456789"
|
81
|
-
|
82
|
-
|
83
|
-
/*
|
84
|
-
***************************************************************************
|
85
|
-
* Macro functions definitions.
|
86
|
-
***************************************************************************
|
87
|
-
*/
|
88
|
-
|
89
|
-
/* Allocate and init structure */
|
90
|
-
#define SREALLOC(S, TYPE, SIZE) do { \
|
91
|
-
TYPE *_p_; \
|
92
|
-
_p_ = S; \
|
93
|
-
if (SIZE) { \
|
94
|
-
if ((S = (TYPE *) realloc(S, (SIZE))) == NULL) { \
|
95
|
-
perror("realloc"); \
|
96
|
-
exit(4); \
|
97
|
-
} \
|
98
|
-
/* If the ptr was null, then it's a malloc() */ \
|
99
|
-
if (!_p_) \
|
100
|
-
memset(S, 0, (SIZE)); \
|
101
|
-
} \
|
102
|
-
} while (0)
|
103
|
-
|
104
|
-
/*
|
105
|
-
* Macros used to display statistics values.
|
106
|
-
*
|
107
|
-
* NB: Define SP_VALUE() to normalize to %;
|
108
|
-
* HZ is 1024 on IA64 and % should be normalized to 100.
|
109
|
-
*/
|
110
|
-
#define S_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * HZ)
|
111
|
-
#define SP_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * 100)
|
112
|
-
|
113
|
-
/*
|
114
|
-
* Under very special circumstances, STDOUT may become unavailable.
|
115
|
-
* This is what we try to guess here
|
116
|
-
*/
|
117
|
-
#define TEST_STDOUT(_fd_) do { \
|
118
|
-
if (write(_fd_, "", 0) == -1) { \
|
119
|
-
perror("stdout"); \
|
120
|
-
exit(6); \
|
121
|
-
} \
|
122
|
-
} while (0)
|
123
|
-
|
124
|
-
|
125
|
-
#define MINIMUM(a,b) ((a) < (b) ? (a) : (b))
|
126
|
-
|
127
|
-
#define PANIC(m) sysstat_panic(__FUNCTION__, m)
|
128
|
-
|
129
|
-
|
130
|
-
/* Number of ticks per second */
|
131
|
-
#define HZ hz
|
132
|
-
extern unsigned int hz;
|
133
|
-
|
134
|
-
/* Number of bit shifts to convert pages to kB */
|
135
|
-
extern unsigned int kb_shift;
|
136
|
-
|
137
|
-
/*
|
138
|
-
* kB <-> number of pages.
|
139
|
-
* Page size depends on machine architecture (4 kB, 8 kB, 16 kB, 64 kB...)
|
140
|
-
*/
|
141
|
-
#define KB_TO_PG(k) ((k) >> kb_shift)
|
142
|
-
#define PG_TO_KB(k) ((k) << kb_shift)
|
143
|
-
|
144
|
-
/*
|
145
|
-
***************************************************************************
|
146
|
-
* Structures definitions
|
147
|
-
***************************************************************************
|
148
|
-
*/
|
149
|
-
|
150
|
-
/* Structure used for extended disk statistics */
|
151
|
-
struct ext_disk_stats {
|
152
|
-
double util;
|
153
|
-
double await;
|
154
|
-
double svctm;
|
155
|
-
double arqsz;
|
156
|
-
};
|
157
|
-
|
158
|
-
|
159
|
-
/*
|
160
|
-
***************************************************************************
|
161
|
-
* Functions prototypes
|
162
|
-
***************************************************************************
|
163
|
-
*/
|
164
|
-
|
165
|
-
extern void
|
166
|
-
compute_ext_disk_stats(struct stats_disk *, struct stats_disk *,
|
167
|
-
unsigned long long, struct ext_disk_stats *);
|
168
|
-
extern int
|
169
|
-
count_bits(void *, int);
|
170
|
-
extern int
|
171
|
-
count_csvalues(int, char **);
|
172
|
-
extern char *
|
173
|
-
device_name(char *);
|
174
|
-
extern void
|
175
|
-
get_HZ(void);
|
176
|
-
extern unsigned int
|
177
|
-
get_devmap_major(void);
|
178
|
-
extern unsigned long long
|
179
|
-
get_interval(unsigned long long, unsigned long long);
|
180
|
-
extern void
|
181
|
-
get_kb_shift(void);
|
182
|
-
extern time_t
|
183
|
-
get_localtime(struct tm *);
|
184
|
-
extern time_t
|
185
|
-
get_time(struct tm *);
|
186
|
-
unsigned long long
|
187
|
-
get_per_cpu_interval(struct stats_cpu *, struct stats_cpu *);
|
188
|
-
extern int
|
189
|
-
get_sysfs_dev_nr(int);
|
190
|
-
extern int
|
191
|
-
get_win_height(void);
|
192
|
-
extern void
|
193
|
-
init_nls(void);
|
194
|
-
extern int
|
195
|
-
is_device(char *);
|
196
|
-
extern double
|
197
|
-
ll_s_value(unsigned long long, unsigned long long, unsigned long long);
|
198
|
-
extern double
|
199
|
-
ll_sp_value(unsigned long long, unsigned long long, unsigned long long);
|
200
|
-
extern int
|
201
|
-
print_gal_header(struct tm *, char *, char *, char *, char *, int);
|
202
|
-
extern void
|
203
|
-
print_version(void);
|
204
|
-
extern void
|
205
|
-
sysstat_panic(const char *, int);
|
206
|
-
|
207
|
-
#endif /* _COMMON_H */
|
@@ -1,515 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* ioconf: ioconf configuration file handling code
|
3
|
-
* Original code (C) 2004 by Red Hat (Charlie Bennett <ccb@redhat.com>)
|
4
|
-
*
|
5
|
-
* Modified and maintained by Sebastien GODARD (sysstat <at> orange.fr)
|
6
|
-
*
|
7
|
-
***************************************************************************
|
8
|
-
* This program is free software; you can redistribute it and/or modify it *
|
9
|
-
* under the terms of the GNU General Public License as published by the *
|
10
|
-
* Free Software Foundation; either version 2 of the License, or (at your *
|
11
|
-
* option) any later version. *
|
12
|
-
* *
|
13
|
-
* This program is distributed in the hope that it will be useful, but *
|
14
|
-
* WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
|
15
|
-
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
16
|
-
* for more details. *
|
17
|
-
* *
|
18
|
-
* You should have received a copy of the GNU General Public License along *
|
19
|
-
* with this program; if not, write to the Free Software Foundation, Inc., *
|
20
|
-
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
21
|
-
***************************************************************************
|
22
|
-
*/
|
23
|
-
|
24
|
-
#include <stdio.h>
|
25
|
-
#include <stdlib.h>
|
26
|
-
#include <string.h>
|
27
|
-
#include <errno.h>
|
28
|
-
#include <dirent.h>
|
29
|
-
#include <sys/stat.h>
|
30
|
-
|
31
|
-
#include "ioconf.h"
|
32
|
-
#include "common.h"
|
33
|
-
|
34
|
-
#ifdef USE_NLS
|
35
|
-
#include <locale.h>
|
36
|
-
#include <libintl.h>
|
37
|
-
#define _(string) gettext(string)
|
38
|
-
#else
|
39
|
-
#define _(string) (string)
|
40
|
-
#endif
|
41
|
-
|
42
|
-
static unsigned int ioc_parsed = 0;
|
43
|
-
static struct ioc_entry *ioconf[MAX_BLKDEV + 1];
|
44
|
-
static unsigned int ioc_refnr[MAX_BLKDEV + 1];
|
45
|
-
|
46
|
-
/*
|
47
|
-
***************************************************************************
|
48
|
-
* Free ioc_entry structures
|
49
|
-
***************************************************************************
|
50
|
-
*/
|
51
|
-
static void ioc_free(void)
|
52
|
-
{
|
53
|
-
unsigned int i;
|
54
|
-
struct ioc_entry **p;
|
55
|
-
|
56
|
-
/* Take out all of the references first */
|
57
|
-
for (i = 0, p = ioconf; i < MAX_BLKDEV; ++i, ++p) {
|
58
|
-
if ((*p == NULL) || ((*p)->live))
|
59
|
-
continue;
|
60
|
-
|
61
|
-
if ((*p)->desc != (*p)->blkp->desc) {
|
62
|
-
/* Not a shared description */
|
63
|
-
free((*p)->desc);
|
64
|
-
}
|
65
|
-
free(*p);
|
66
|
-
*p = NULL;
|
67
|
-
}
|
68
|
-
|
69
|
-
/* Now the live ones */
|
70
|
-
for (i = 0, p = ioconf; i < MAX_BLKDEV; ++i, ++p) {
|
71
|
-
if (*p == NULL)
|
72
|
-
continue;
|
73
|
-
free((*p)->blkp);
|
74
|
-
free(*p);
|
75
|
-
*p = NULL;
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
/*
|
80
|
-
***************************************************************************
|
81
|
-
* ioc_conv - Turn a number into a string in radix <radix> using symbol
|
82
|
-
* set (and ordering) syms. Use nozero to generate strings
|
83
|
-
* in which the number system uses a single sym for the
|
84
|
-
* radix value (not 2, like decimal) and adds a column only
|
85
|
-
* at radix+1. If decimal were like this:
|
86
|
-
*
|
87
|
-
* (no zero) 1 2 3 4 5 6 7 8 9 0 11 12 13 14 15 16 17 18 19 10 ...
|
88
|
-
***************************************************************************
|
89
|
-
*/
|
90
|
-
static char *ioc_conv(int radix, int nozero, const char *syms,
|
91
|
-
unsigned int val)
|
92
|
-
{
|
93
|
-
static char out[17];
|
94
|
-
char *p;
|
95
|
-
int j;
|
96
|
-
|
97
|
-
*(p = out + 16) = '\0';
|
98
|
-
|
99
|
-
val += nozero;
|
100
|
-
|
101
|
-
if (val == 0) {
|
102
|
-
if (!nozero) {
|
103
|
-
*--p = '0';
|
104
|
-
}
|
105
|
-
return (p); /* Empty string if nozero radix gets val == 0 */
|
106
|
-
}
|
107
|
-
|
108
|
-
while (val > 0) {
|
109
|
-
*--p = syms[j = val % radix];
|
110
|
-
val /= radix;
|
111
|
-
if (nozero && (j == 0)) {
|
112
|
-
/* Comp for 10 in nozero bases */
|
113
|
-
--val;
|
114
|
-
}
|
115
|
-
}
|
116
|
-
return (p);
|
117
|
-
}
|
118
|
-
|
119
|
-
char *ioc_ito10(unsigned int n)
|
120
|
-
{
|
121
|
-
return (ioc_conv(10, 0, "0123456789", n));
|
122
|
-
}
|
123
|
-
|
124
|
-
char *ioc_ito26(unsigned int n)
|
125
|
-
{
|
126
|
-
return (ioc_conv(26, 1, "zabcdefghijklmnopqrstuvwxy", n));
|
127
|
-
}
|
128
|
-
|
129
|
-
/*
|
130
|
-
***************************************************************************
|
131
|
-
* ioc_init() - internalize the ioconf file
|
132
|
-
*
|
133
|
-
* given: void
|
134
|
-
* does: parses IOCONF into ioconf, an array of ioc_entry *
|
135
|
-
* Only entries having lines in IOCONF will have valid pointers
|
136
|
-
* return: 1 on success
|
137
|
-
* 0 on failure
|
138
|
-
***************************************************************************
|
139
|
-
*/
|
140
|
-
int ioc_init(void)
|
141
|
-
{
|
142
|
-
FILE *fp;
|
143
|
-
unsigned int i, major, indirect, count = 0;
|
144
|
-
char buf[IOC_LINESIZ + 1];
|
145
|
-
char cfmt[IOC_FMTLEN + 1];
|
146
|
-
char dfmt[IOC_FMTLEN + 1];
|
147
|
-
char pfmt[IOC_FMTLEN + 1];
|
148
|
-
char desc[IOC_DESCLEN + 1];
|
149
|
-
struct ioc_entry *iocp = NULL;
|
150
|
-
struct blk_config *blkp = NULL;
|
151
|
-
char ioconf_name[64];
|
152
|
-
|
153
|
-
if ((fp = fopen(IOCONF, "r")) == NULL) {
|
154
|
-
if ((fp = fopen(LOCAL_IOCONF, "r")) == NULL)
|
155
|
-
return 0;
|
156
|
-
strncpy(ioconf_name, LOCAL_IOCONF, 64);
|
157
|
-
}
|
158
|
-
else {
|
159
|
-
strncpy(ioconf_name, IOCONF, 64);
|
160
|
-
}
|
161
|
-
ioconf_name[63] = '\0';
|
162
|
-
|
163
|
-
/* Init ioc_refnr array */
|
164
|
-
memset(ioc_refnr, 0, sizeof(ioc_refnr));
|
165
|
-
|
166
|
-
while (fgets(buf, IOC_LINESIZ, fp)) {
|
167
|
-
|
168
|
-
if ((*buf == '#') || (*buf == '\n'))
|
169
|
-
continue;
|
170
|
-
|
171
|
-
/*
|
172
|
-
* Preallocate some (probably) needed data structures
|
173
|
-
*/
|
174
|
-
IOC_ALLOC(blkp, struct blk_config, BLK_CONFIG_SIZE);
|
175
|
-
IOC_ALLOC(iocp, struct ioc_entry, IOC_ENTRY_SIZE);
|
176
|
-
memset(blkp, 0, BLK_CONFIG_SIZE);
|
177
|
-
memset(iocp, 0, IOC_ENTRY_SIZE);
|
178
|
-
|
179
|
-
i = sscanf(buf, "%u:%u:%u:%s",
|
180
|
-
&major, &indirect, &iocp->ctrlno, desc);
|
181
|
-
|
182
|
-
if (i != 4) {
|
183
|
-
i = sscanf(buf, "%u:%u:%u",
|
184
|
-
&major, &indirect, &iocp->ctrlno);
|
185
|
-
}
|
186
|
-
|
187
|
-
if ((i == 3) || (i == 4)) {
|
188
|
-
/* indirect record */
|
189
|
-
if (indirect == 0) {
|
190
|
-
/* conventional usage for unsupported device */
|
191
|
-
continue;
|
192
|
-
}
|
193
|
-
if (indirect >= MAX_BLKDEV) {
|
194
|
-
fprintf(stderr, "%s: Indirect major #%u out of range\n",
|
195
|
-
ioconf_name, indirect);
|
196
|
-
continue;
|
197
|
-
}
|
198
|
-
if (ioconf[indirect] == NULL) {
|
199
|
-
fprintf(stderr,
|
200
|
-
"%s: Indirect record '%u:%u:%u:...'"
|
201
|
-
" references not yet seen major %u\n",
|
202
|
-
ioconf_name, major, indirect, iocp->ctrlno, major);
|
203
|
-
continue;
|
204
|
-
}
|
205
|
-
/*
|
206
|
-
* Cool. Point this device at its referent.
|
207
|
-
* Skip last: (last field my be empty...)
|
208
|
-
* if it was empty and : was in the sscanf spec
|
209
|
-
* we'd only see 3 fields...
|
210
|
-
*/
|
211
|
-
if (i == 3) {
|
212
|
-
/* reference the mothership */
|
213
|
-
iocp->desc = ioconf[indirect]->blkp->desc;
|
214
|
-
}
|
215
|
-
else {
|
216
|
-
IOC_ALLOC(iocp->desc, char, IOC_DESCLEN + 1);
|
217
|
-
strncpy(iocp->desc, desc, IOC_DESCLEN);
|
218
|
-
}
|
219
|
-
ioc_refnr[indirect]++;
|
220
|
-
ioconf[major] = iocp;
|
221
|
-
iocp->basemajor = indirect;
|
222
|
-
iocp->blkp = ioconf[indirect]->blkp;
|
223
|
-
iocp->live = 0;
|
224
|
-
iocp = NULL;
|
225
|
-
continue;
|
226
|
-
/* all done with indirect record */
|
227
|
-
}
|
228
|
-
|
229
|
-
/* maybe it's a full record? */
|
230
|
-
|
231
|
-
i = sscanf(buf, "%u:%[^:]:%[^:]:%d:%[^:]:%u:%[^:]:%u:%s",
|
232
|
-
&major, blkp->name,
|
233
|
-
cfmt, &iocp->ctrlno,
|
234
|
-
dfmt, &blkp->dcount,
|
235
|
-
pfmt, &blkp->pcount,
|
236
|
-
desc);
|
237
|
-
|
238
|
-
if (i != 9) {
|
239
|
-
fprintf(stderr, "%s: Malformed %d field record: %s\n",
|
240
|
-
ioconf_name, i, buf);
|
241
|
-
continue;
|
242
|
-
}
|
243
|
-
|
244
|
-
/* this is a full-fledged direct record */
|
245
|
-
|
246
|
-
if ((major == 0) || (major >= MAX_BLKDEV)) {
|
247
|
-
fprintf(stderr, "%s: major #%u out of range\n",
|
248
|
-
__FUNCTION__, major);
|
249
|
-
continue;
|
250
|
-
}
|
251
|
-
|
252
|
-
/* is this an exception record? */
|
253
|
-
if (*cfmt == 'x') {
|
254
|
-
struct blk_config *xblkp;
|
255
|
-
|
256
|
-
/*
|
257
|
-
* device has an aliased minor
|
258
|
-
* for now we only support on exception per major
|
259
|
-
* (catering to initrd: (1,250))
|
260
|
-
*/
|
261
|
-
if (ioconf[major] == NULL) {
|
262
|
-
fprintf(stderr, "%s: type 'x' record for"
|
263
|
-
" major #%u must follow the base record - ignored\n",
|
264
|
-
ioconf_name, major);
|
265
|
-
continue;
|
266
|
-
}
|
267
|
-
xblkp = ioconf[major]->blkp;
|
268
|
-
|
269
|
-
if (xblkp->ext) {
|
270
|
-
/*
|
271
|
-
* Enforce one minor exception per major policy
|
272
|
-
* note: this applies to each major number and
|
273
|
-
* all of it's indirect (short form) majors
|
274
|
-
*/
|
275
|
-
fprintf(stderr, "%s: duplicate 'x' record for"
|
276
|
-
" major #%u - ignored\ninput line: %s\n",
|
277
|
-
ioconf_name, major, buf);
|
278
|
-
continue;
|
279
|
-
}
|
280
|
-
/*
|
281
|
-
* Decorate the base major struct with the
|
282
|
-
* exception info
|
283
|
-
*/
|
284
|
-
xblkp->ext_minor = iocp->ctrlno;
|
285
|
-
strcpy(xblkp->ext_name, blkp->name);
|
286
|
-
xblkp->ext = 1;
|
287
|
-
continue;
|
288
|
-
}
|
289
|
-
|
290
|
-
/*
|
291
|
-
* Preformat the sprintf format strings for generating
|
292
|
-
* c-d-p info in ioc_name()
|
293
|
-
*/
|
294
|
-
|
295
|
-
/* basename of device + provided string + controller # */
|
296
|
-
if (*cfmt == '*') {
|
297
|
-
strcpy(blkp->cfmt, blkp->name);
|
298
|
-
}
|
299
|
-
else {
|
300
|
-
sprintf(blkp->cfmt, "%s%s%%d", blkp->name, cfmt);
|
301
|
-
++(blkp->ctrl_explicit);
|
302
|
-
}
|
303
|
-
|
304
|
-
/* Disk */
|
305
|
-
*blkp->dfmt = '\0';
|
306
|
-
switch (*dfmt) {
|
307
|
-
case 'a':
|
308
|
-
blkp->cconv = ioc_ito26;
|
309
|
-
strcpy(blkp->dfmt, "%s");
|
310
|
-
break;
|
311
|
-
|
312
|
-
case '%':
|
313
|
-
strcpy(blkp->dfmt, dfmt + 1);
|
314
|
-
case 'd':
|
315
|
-
blkp->cconv = ioc_ito10;
|
316
|
-
strcat(blkp->dfmt, "%s");
|
317
|
-
break;
|
318
|
-
}
|
319
|
-
|
320
|
-
/* Partition */
|
321
|
-
sprintf(blkp->pfmt, "%s%%d", (*pfmt == '*') ? "" : pfmt);
|
322
|
-
|
323
|
-
/*
|
324
|
-
* We're good to go.
|
325
|
-
* Stuff the ioc_entry and ref it.
|
326
|
-
*/
|
327
|
-
iocp->live = 1;
|
328
|
-
iocp->blkp = blkp;
|
329
|
-
iocp->desc = NULL;
|
330
|
-
iocp->basemajor = major;
|
331
|
-
ioconf[major] = iocp;
|
332
|
-
strncpy(blkp->desc, desc, IOC_DESCLEN);
|
333
|
-
blkp = NULL; iocp = NULL;
|
334
|
-
++count;
|
335
|
-
}
|
336
|
-
fclose(fp);
|
337
|
-
|
338
|
-
/*
|
339
|
-
* These will become leaks if we ever 'continue'
|
340
|
-
* after IOC_ALLOC( blkp->desc ... ).
|
341
|
-
* Right Now, we don't.
|
342
|
-
*/
|
343
|
-
if (blkp != NULL)
|
344
|
-
free(blkp);
|
345
|
-
if (iocp != NULL)
|
346
|
-
free(iocp);
|
347
|
-
|
348
|
-
/* Indicate that ioconf file has been parsed */
|
349
|
-
ioc_parsed = 1;
|
350
|
-
|
351
|
-
return (count);
|
352
|
-
}
|
353
|
-
|
354
|
-
/*
|
355
|
-
***************************************************************************
|
356
|
-
* ioc_name() - Generate a name from a maj,min pair
|
357
|
-
*
|
358
|
-
* IN:
|
359
|
-
* @major Device major number.
|
360
|
-
* @minor Device minor number.
|
361
|
-
*
|
362
|
-
* RETURNS:
|
363
|
-
* Returns NULL if major or minor are out of range
|
364
|
-
* otherwise returns a pointer to a static string containing
|
365
|
-
* the generated name.
|
366
|
-
***************************************************************************
|
367
|
-
*/
|
368
|
-
|
369
|
-
char *ioc_name(unsigned int major, unsigned int minor)
|
370
|
-
{
|
371
|
-
static char name[IOC_DEVLEN + 1];
|
372
|
-
struct ioc_entry *p;
|
373
|
-
int base, offset;
|
374
|
-
|
375
|
-
if ((MAX_BLKDEV <= major) || (IOC_MAXMINOR <= minor)) {
|
376
|
-
return (NULL);
|
377
|
-
}
|
378
|
-
|
379
|
-
if (!ioc_parsed && !ioc_init())
|
380
|
-
return (NULL);
|
381
|
-
|
382
|
-
p = ioconf[major];
|
383
|
-
|
384
|
-
/* Invalid major or minor numbers? */
|
385
|
-
if ((p == NULL) || ((minor & 0xff) >= (p->blkp->dcount * p->blkp->pcount))) {
|
386
|
-
/*
|
387
|
-
* That minor test is only there for IDE-style devices
|
388
|
-
* that have no minors over 128.
|
389
|
-
*/
|
390
|
-
strcpy(name, K_NODEV);
|
391
|
-
return (name);
|
392
|
-
}
|
393
|
-
|
394
|
-
/* Is this an extension record? */
|
395
|
-
if (p->blkp->ext && (p->blkp->ext_minor == minor)) {
|
396
|
-
strcpy(name, p->blkp->ext_name);
|
397
|
-
return (name);
|
398
|
-
}
|
399
|
-
|
400
|
-
/* OK. we're doing an actual device name... */
|
401
|
-
|
402
|
-
/*
|
403
|
-
* Assemble base + optional controller info
|
404
|
-
* this is of course too clever by half
|
405
|
-
* the parser has already cooked cfmt, dfmt to make this easy
|
406
|
-
* (we parse once but may generate lots of names)
|
407
|
-
*/
|
408
|
-
base = p->ctrlno * p->blkp->dcount;
|
409
|
-
if (minor >= 256) {
|
410
|
-
base += p->blkp->dcount * (ioc_refnr[p->basemajor] + 1) * (minor >> 8);
|
411
|
-
}
|
412
|
-
|
413
|
-
offset = (minor & 0xff) / p->blkp->pcount;
|
414
|
-
if (!p->blkp->ctrl_explicit) {
|
415
|
-
offset += base;
|
416
|
-
}
|
417
|
-
|
418
|
-
/*
|
419
|
-
* These sprintfs can't be coalesced because the first might
|
420
|
-
* ignore its first arg
|
421
|
-
*/
|
422
|
-
sprintf(name, p->blkp->cfmt, p->ctrlno);
|
423
|
-
sprintf(name + strlen(name), p->blkp->dfmt, p->blkp->cconv(offset));
|
424
|
-
|
425
|
-
if (!IS_WHOLE(major, minor)) {
|
426
|
-
/*
|
427
|
-
* Tack on partition info, format string cooked (curried?) by
|
428
|
-
* the parser
|
429
|
-
*/
|
430
|
-
sprintf(name + strlen(name), p->blkp->pfmt, minor % p->blkp->pcount);
|
431
|
-
}
|
432
|
-
return (name);
|
433
|
-
}
|
434
|
-
|
435
|
-
/*
|
436
|
-
***************************************************************************
|
437
|
-
* Check whether a device is a whole disk device or not.
|
438
|
-
*
|
439
|
-
* IN:
|
440
|
-
* @major Device major number.
|
441
|
-
* @minor Device minor number.
|
442
|
-
*
|
443
|
-
* RETURNS:
|
444
|
-
* Predicate: Returns 1 if dev (major,minor) is a whole disk device.
|
445
|
-
* Returns 0 otherwise.
|
446
|
-
***************************************************************************
|
447
|
-
*/
|
448
|
-
int ioc_iswhole(unsigned int major, unsigned int minor)
|
449
|
-
{
|
450
|
-
if (!ioc_parsed && !ioc_init())
|
451
|
-
return 0;
|
452
|
-
|
453
|
-
if (major >= MAX_BLKDEV)
|
454
|
-
/*
|
455
|
-
* Later: Handle Linux long major numbers here.
|
456
|
-
* Now: This is an error.
|
457
|
-
*/
|
458
|
-
return 0;
|
459
|
-
|
460
|
-
if (ioconf[major] == NULL)
|
461
|
-
/* Device not registered */
|
462
|
-
return 0 ;
|
463
|
-
|
464
|
-
return (IS_WHOLE(major, minor));
|
465
|
-
}
|
466
|
-
|
467
|
-
/*
|
468
|
-
***************************************************************************
|
469
|
-
* Transform device mapper name: Get the user assigned name of the logical
|
470
|
-
* device instead of the internal device mapper numbering.
|
471
|
-
*
|
472
|
-
* IN:
|
473
|
-
* @major Device major number.
|
474
|
-
* @minor Device minor number.
|
475
|
-
*
|
476
|
-
* RETURNS:
|
477
|
-
* Assigned name of the logical device.
|
478
|
-
***************************************************************************
|
479
|
-
*/
|
480
|
-
char *transform_devmapname(unsigned int major, unsigned int minor)
|
481
|
-
{
|
482
|
-
DIR *dm_dir;
|
483
|
-
struct dirent *dp;
|
484
|
-
char filen[MAX_FILE_LEN];
|
485
|
-
char *dm_name = NULL;
|
486
|
-
struct stat aux;
|
487
|
-
unsigned int dm_major, dm_minor;
|
488
|
-
|
489
|
-
if ((dm_dir = opendir(DEVMAP_DIR)) == NULL) {
|
490
|
-
fprintf(stderr, _("Cannot open %s: %s\n"), DEVMAP_DIR, strerror(errno));
|
491
|
-
exit(4);
|
492
|
-
}
|
493
|
-
|
494
|
-
while ((dp = readdir(dm_dir)) != NULL) {
|
495
|
-
/* For each file in DEVMAP_DIR */
|
496
|
-
|
497
|
-
snprintf(filen, MAX_FILE_LEN, "%s/%s", DEVMAP_DIR, dp->d_name);
|
498
|
-
filen[MAX_FILE_LEN - 1] = '\0';
|
499
|
-
|
500
|
-
if (stat(filen, &aux) == 0) {
|
501
|
-
/* Get its minor and major numbers */
|
502
|
-
|
503
|
-
dm_major = ((aux.st_rdev >> 8) & 0xff);
|
504
|
-
dm_minor = (aux.st_rdev & 0xff);
|
505
|
-
|
506
|
-
if ((dm_minor == minor) && (dm_major == major)) {
|
507
|
-
dm_name = dp->d_name;
|
508
|
-
break;
|
509
|
-
}
|
510
|
-
}
|
511
|
-
}
|
512
|
-
closedir(dm_dir);
|
513
|
-
|
514
|
-
return dm_name;
|
515
|
-
}
|