Statistics
| Branch: | Revision:

root / control / tap-ctl-stats.c @ abdb293f

History | View | Annotate | Download (3.7 kB)

1
/*
2
 * Copyright (c) 2010, Citrix 
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 are met:
7
 *     * Redistributions of source code must retain the above copyright
8
 *       notice, this list of conditions and the following disclaimer.
9
 *     * Redistributions in binary form must reproduce the above copyright
10
 *       notice, this list of conditions and the following disclaimer in the
11
 *       documentation and/or other materials provided with the distribution.
12
 *     * Neither the name of XenSource Inc. nor the names of its contributors
13
 *       may be used to endorse or promote products derived from this software
14
 *       without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28

    
29
#ifdef HAVE_CONFIG_H
30
#include "config.h"
31
#endif
32

    
33
#include <stdio.h>
34
#include <string.h>
35
#include <unistd.h>
36
#include <sys/mman.h>
37

    
38
#include "tap-ctl.h"
39

    
40
int
41
_tap_ctl_stats_connect_and_send(pid_t pid, int minor)
42
{
43
        struct timeval timeout = { .tv_sec = 10, .tv_usec = 0 };
44
        tapdisk_message_t message;
45
        int sfd, err;
46

    
47
        err = tap_ctl_connect_id(pid, &sfd);
48
        if (err)
49
                return err;
50

    
51
        memset(&message, 0, sizeof(message));
52
        message.type   = TAPDISK_MESSAGE_STATS;
53
        message.cookie = minor;
54

    
55
        err = tap_ctl_write_message(sfd, &message, &timeout);
56
        if (err)
57
                return err;
58

    
59
        return sfd;
60
}
61

    
62
ssize_t
63
tap_ctl_stats(pid_t pid, int minor, char *buf, size_t size)
64
{
65
        tapdisk_message_t message;
66
        int sfd, err;
67
        size_t len;
68

    
69
        sfd = _tap_ctl_stats_connect_and_send(pid, minor);
70
        if (sfd < 0)
71
                return sfd;
72

    
73
        err = tap_ctl_read_message(sfd, &message, NULL);
74
        if (err)
75
                return err;
76

    
77
        len= message.u.info.length;
78
        if (len < 0) {
79
                err = len;
80
                goto out;
81
        }
82
        if (size < len + 1)
83
                len = size - 1;
84

    
85
        err = tap_ctl_read_raw(sfd, buf, len, NULL);
86
        if (err)
87
                goto out;
88

    
89
        buf[len] = 0;
90

    
91
out:
92
        close(sfd);
93
        return err;
94
}
95

    
96
int
97
tap_ctl_stats_fwrite(pid_t pid, int minor, FILE *stream)
98
{
99
        tapdisk_message_t message;
100
        int sfd = -1, prot, flags, err;
101
        size_t len, bufsz;
102
        char *buf = MAP_FAILED;
103

    
104
        prot  = PROT_READ|PROT_WRITE;
105
        flags = MAP_ANONYMOUS|MAP_PRIVATE;
106
        bufsz = sysconf(_SC_PAGE_SIZE);
107

    
108
        buf = mmap(NULL, bufsz, prot, flags, -1, 0);
109
        if (buf == MAP_FAILED) {
110
                buf = NULL;
111
                err = -ENOMEM;
112
                goto out;
113
        }
114

    
115
        sfd = _tap_ctl_stats_connect_and_send(pid, minor);
116
        if (sfd < 0) {
117
                err = sfd;
118
                goto out;
119
        }
120

    
121
        err = tap_ctl_read_message(sfd, &message, NULL);
122
        if (err)
123
                goto out;
124

    
125
        len = message.u.info.length;
126
        err = len;
127
        if (len < 0)
128
                goto out;
129

    
130
        while (len) {
131
                fd_set rfds;
132
                size_t in, out;
133
                int n;
134

    
135
                FD_ZERO(&rfds);
136
                FD_SET(sfd, &rfds);
137

    
138
                n = select(sfd + 1, &rfds, NULL, NULL, NULL);
139
                err = n;
140
                if (n < 0)
141
                        goto out;
142

    
143
                in = read(sfd, buf, bufsz);
144
                err = in;
145
                if (in <= 0)
146
                        goto out;
147

    
148
                len -= in;
149

    
150
                out = fwrite(buf, in, 1, stream);
151
                if (out != in) {
152
                        err = -errno;
153
                        goto out;
154
                }
155
        }
156

    
157
out:
158
        if (sfd >= 0)
159
                close(sfd);
160
        if (buf != MAP_FAILED)
161
                munmap(buf, bufsz);
162

    
163
        return err;
164
}