Statistics
| Branch: | Revision:

root / drivers / tapdisk-utils.c @ abdb293f

History | View | Annotate | Download (6 kB)

1
/* 
2
 * Copyright (c) 2008, XenSource Inc.
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 <stdlib.h>
34
#include <errno.h>
35
#include <stdio.h>
36
#include <string.h>
37
#include <unistd.h>
38
#include <linux/fs.h>
39
#include <sys/stat.h>
40
#include <sys/mman.h>
41
#include <sys/ioctl.h>
42
#include <sys/resource.h>
43
#include <sys/utsname.h>
44
#ifdef __linux__
45
#include <linux/version.h>
46
#endif
47

    
48
#define SYSLOG_NAMES
49
#include <syslog.h>
50

    
51
#include "tapdisk.h"
52
#include "tapdisk-log.h"
53
#include "tapdisk-utils.h"
54
#include "tapdisk-syslog.h"
55

    
56
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
57

    
58
static int
59
tapdisk_syslog_facility_by_name(const char *name)
60
{
61
        int facility;
62
        CODE *c;
63

    
64
        facility = -1;
65

    
66
        for (c = facilitynames; c->c_name != NULL; ++c)
67
                if (!strcmp(c->c_name, name)) {
68
                        facility = c->c_val;
69
                        break;
70
                }
71

    
72
        return facility;
73
}
74

    
75
int
76
tapdisk_syslog_facility(const char *arg)
77
{
78
        int facility;
79
        char *endptr;
80

    
81
        if (arg) {
82
                facility = strtol(arg, &endptr, 0);
83
                if (*endptr == 0)
84
                        return facility;
85

    
86
                facility = tapdisk_syslog_facility_by_name(arg);
87
                if (facility >= 0)
88
                        return facility;
89
        }
90

    
91
        return LOG_DAEMON;
92
}
93

    
94
char*
95
tapdisk_syslog_ident(const char *name)
96
{
97
        char ident[TD_SYSLOG_IDENT_MAX+1];
98
        size_t size, len;
99
        pid_t pid;
100

    
101
        pid  = getpid();
102
        size = sizeof(ident);
103
        len  = 0;
104

    
105
        len  = snprintf(NULL, 0, "[%d]", pid);
106
        len  = snprintf(ident, size - len, "%s", name);
107
        len += snprintf(ident + len, size - len, "[%d]", pid);
108

    
109
        return strdup(ident);
110
}
111

    
112
size_t
113
tapdisk_syslog_strftime(char *buf, size_t size, const struct timeval *tv)
114
{
115
        const char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
116
                              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
117
        struct tm tm;
118

    
119
        /*
120
         * TIMESTAMP :=  <Mmm> " " <dd> " " <hh> ":" <mm> ":" <ss>.
121
         * Local time, no locales.
122
         */
123

    
124
        localtime_r(&tv->tv_sec, &tm);
125

    
126
        return snprintf(buf, size, "%s %2d %02d:%02d:%02d",
127
                        mon[tm.tm_mon], tm.tm_mday,
128
                        tm.tm_hour, tm.tm_min, tm.tm_sec);
129
}
130

    
131
size_t
132
tapdisk_syslog_strftv(char *buf, size_t size, const struct timeval *tv)
133
{
134
        struct tm tm;
135

    
136
        localtime_r(&tv->tv_sec, &tm);
137

    
138
        return snprintf(buf, size, "[%02d:%02d:%02d.%03ld]",
139
                        tm.tm_hour, tm.tm_min, tm.tm_sec,
140
                        (long)tv->tv_usec / 1000);
141
}
142

    
143
int
144
tapdisk_set_resource_limits(void)
145
{
146
        int err;
147
        struct rlimit rlim;
148

    
149
        rlim.rlim_cur = RLIM_INFINITY;
150
        rlim.rlim_max = RLIM_INFINITY;
151

    
152
        err = setrlimit(RLIMIT_MEMLOCK, &rlim);
153
        if (err == -1) {
154
                EPRINTF("RLIMIT_MEMLOCK failed: %d\n", errno);
155
                return -errno;
156
        }
157

    
158
        err = mlockall(MCL_CURRENT | MCL_FUTURE);
159
        if (err == -1) {
160
                EPRINTF("mlockall failed: %d\n", errno);
161
                return -errno;
162
        }
163

    
164
#define CORE_DUMP
165
#if defined(CORE_DUMP)
166
        err = setrlimit(RLIMIT_CORE, &rlim);
167
        if (err == -1)
168
                EPRINTF("RLIMIT_CORE failed: %d\n", errno);
169
#endif
170

    
171
        return 0;
172
}
173

    
174
int
175
tapdisk_namedup(char **dup, const char *name)
176
{
177
        *dup = NULL;
178

    
179
        if (strnlen(name, MAX_NAME_LEN) >= MAX_NAME_LEN)
180
                return -ENAMETOOLONG;
181
        
182
        *dup = strdup(name);
183
        if (!*dup)
184
                return -ENOMEM;
185

    
186
        return 0;
187
}
188

    
189
/*Get Image size, secsize*/
190
int
191
tapdisk_get_image_size(int fd, uint64_t *_sectors, uint32_t *_sector_size)
192
{
193
        struct stat stat;
194
        uint64_t sectors, bytes;
195
        uint32_t sector_size;
196

    
197
        sectors       = 0;
198
        sector_size   = 0;
199
        *_sectors     = 0;
200
        *_sector_size = 0;
201

    
202
        if (fstat(fd, &stat)) {
203
                DPRINTF("ERROR: fstat failed, Couldn't stat image");
204
                return -EINVAL;
205
        }
206

    
207
        if (S_ISBLK(stat.st_mode)) {
208
                /*Accessing block device directly*/
209
                if (ioctl(fd,BLKGETSIZE64,&bytes)==0) {
210
                        sectors = bytes >> SECTOR_SHIFT;
211
                } else if (ioctl(fd,BLKGETSIZE,&sectors)!=0) {
212
                        DPRINTF("ERR: BLKGETSIZE and BLKGETSIZE64 failed, couldn't stat image");
213
                        return -EINVAL;
214
                }
215

    
216
                /*Get the sector size*/
217
#if defined(BLKSSZGET)
218
                {
219
                        sector_size = DEFAULT_SECTOR_SIZE;
220
                        ioctl(fd, BLKSSZGET, &sector_size);
221

    
222
                        if (sector_size != DEFAULT_SECTOR_SIZE)
223
                                DPRINTF("Note: sector size is %u (not %d)\n",
224
                                        sector_size, DEFAULT_SECTOR_SIZE);
225
                }
226
#else
227
                sector_size = DEFAULT_SECTOR_SIZE;
228
#endif
229

    
230
        } else {
231
                /*Local file? try fstat instead*/
232
                sectors     = (stat.st_size >> SECTOR_SHIFT);
233
                sector_size = DEFAULT_SECTOR_SIZE;
234
        }
235

    
236
        if (sectors == 0) {                
237
                sectors     = 16836057ULL;
238
                sector_size = DEFAULT_SECTOR_SIZE;
239
        }
240

    
241
        return 0;
242
}
243

    
244
#ifdef __linux__
245

    
246
int tapdisk_linux_version(void)
247
{
248
        struct utsname uts;
249
        unsigned int version, patchlevel, sublevel;
250
        int n, err;
251

    
252
        err = uname(&uts);
253
        if (err)
254
                return -errno;
255

    
256
        n = sscanf(uts.release, "%u.%u.%u", &version, &patchlevel, &sublevel);
257
        if (n != 3)
258
                return -ENOSYS;
259

    
260
        return KERNEL_VERSION(version, patchlevel, sublevel);
261
}
262

    
263
#else
264

    
265
int tapdisk_linux_version(void)
266
{
267
        return -ENOSYS;
268
}
269

    
270
#endif