~ubuntu-branches/debian/jessie/systemd/jessie

« back to all changes in this revision

Viewing changes to src/readahead/readahead-common.c

  • Committer: Package Import Robot
  • Author(s): Tollef Fog Heen, Tollef Fog Heen, Michael Biebl
  • Date: 2012-04-03 19:59:17 UTC
  • mfrom: (1.1.10) (6.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20120403195917-l532urrbg4pkreas
Tags: 44-1
[ Tollef Fog Heen ]
* New upstream version.
  - Backport 3492207: journal: PAGE_SIZE is not known on ppc and other
    archs
  - Backport 5a2a2a1: journal: react with immediate rotation to a couple
    of more errors
  - Backport 693ce21: util: never follow symlinks in rm_rf_children()
    Fixes CVE-2012-1174, closes: #664364
* Drop output message from init-functions hook, it's pointless.
* Only rmdir /lib/init/rw if it exists.
* Explicitly order debian-fixup before sysinit.target to prevent a
  possible race condition with the creation of sockets.  Thanks to
  Michael Biebl for debugging this.
* Always restart the initctl socket on upgrades, to mask sysvinit
  removing it.

[ Michael Biebl ]
* Remove workaround for non-interactive sessions from pam config again.
* Create compat /dev/initctl symlink in case we are upgrading from a system
  running a newer version of sysvinit (using /run/initctl) and sysvinit is
  replaced with systemd-sysv during the upgrade. Closes: #663219
* Install new man pages.
* Build-Depend on valac (>= 0.12) instead of valac-0.12. Closes: #663323

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
2
 
 
3
/***
 
4
  This file is part of systemd.
 
5
 
 
6
  Copyright 2010 Lennart Poettering
 
7
 
 
8
  systemd is free software; you can redistribute it and/or modify it
 
9
  under the terms of the GNU General Public License as published by
 
10
  the Free Software Foundation; either version 2 of the License, or
 
11
  (at your option) any later version.
 
12
 
 
13
  systemd is distributed in the hope that it will be useful, but
 
14
  WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
16
  General Public License for more details.
 
17
 
 
18
  You should have received a copy of the GNU General Public License
 
19
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
20
***/
 
21
 
 
22
#include <errno.h>
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <sys/sysinfo.h>
 
26
#include <sys/inotify.h>
 
27
#include <fcntl.h>
 
28
#include <sys/mman.h>
 
29
#include <unistd.h>
 
30
#include <libudev.h>
 
31
 
 
32
#include "log.h"
 
33
#include "readahead-common.h"
 
34
#include "util.h"
 
35
 
 
36
int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) {
 
37
        assert(fd >= 0);
 
38
        assert(fn);
 
39
        assert(st);
 
40
 
 
41
        if (fstat(fd, st) < 0) {
 
42
                log_warning("fstat(%s) failed: %m", fn);
 
43
                return -errno;
 
44
        }
 
45
 
 
46
        if (!S_ISREG(st->st_mode)) {
 
47
                log_debug("Not preloading special file %s", fn);
 
48
                return 0;
 
49
        }
 
50
 
 
51
        if (st->st_size <= 0 || st->st_size > file_size_max) {
 
52
                log_debug("Not preloading file %s with size out of bounds %llu", fn, (unsigned long long) st->st_size);
 
53
                return 0;
 
54
        }
 
55
 
 
56
        return 1;
 
57
}
 
58
 
 
59
int fs_on_ssd(const char *p) {
 
60
        struct stat st;
 
61
        struct udev *udev = NULL;
 
62
        struct udev_device *udev_device = NULL, *look_at = NULL;
 
63
        bool b = false;
 
64
        const char *devtype, *rotational, *model, *id;
 
65
 
 
66
        assert(p);
 
67
 
 
68
        if (stat(p, &st) < 0)
 
69
                return -errno;
 
70
 
 
71
        if (major(st.st_dev) == 0)
 
72
                return false;
 
73
 
 
74
        if (!(udev = udev_new()))
 
75
                return -ENOMEM;
 
76
 
 
77
        if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev)))
 
78
                goto finish;
 
79
 
 
80
        if ((devtype = udev_device_get_property_value(udev_device, "DEVTYPE")) &&
 
81
            streq(devtype, "partition"))
 
82
                look_at = udev_device_get_parent(udev_device);
 
83
        else
 
84
                look_at = udev_device;
 
85
 
 
86
        if (!look_at)
 
87
                goto finish;
 
88
 
 
89
        /* First, try high-level property */
 
90
        if ((id = udev_device_get_property_value(look_at, "ID_SSD"))) {
 
91
                b = streq(id, "1");
 
92
                goto finish;
 
93
        }
 
94
 
 
95
        /* Second, try kernel attribute */
 
96
        if ((rotational = udev_device_get_sysattr_value(look_at, "queue/rotational")))
 
97
                if ((b = streq(rotational, "0")))
 
98
                        goto finish;
 
99
 
 
100
        /* Finally, fallback to heuristics */
 
101
        if (!(look_at = udev_device_get_parent(look_at)))
 
102
                goto finish;
 
103
 
 
104
        if ((model = udev_device_get_sysattr_value(look_at, "model")))
 
105
                b = !!strstr(model, "SSD");
 
106
 
 
107
finish:
 
108
        if (udev_device)
 
109
                udev_device_unref(udev_device);
 
110
 
 
111
        if (udev)
 
112
                udev_unref(udev);
 
113
 
 
114
        return b;
 
115
}
 
116
 
 
117
int fs_on_read_only(const char *p) {
 
118
        struct stat st;
 
119
        struct udev *udev = NULL;
 
120
        struct udev_device *udev_device = NULL;
 
121
        bool b = false;
 
122
        const char *read_only;
 
123
 
 
124
        assert(p);
 
125
 
 
126
        if (stat(p, &st) < 0)
 
127
                return -errno;
 
128
 
 
129
        if (major(st.st_dev) == 0)
 
130
                return false;
 
131
 
 
132
        if (!(udev = udev_new()))
 
133
                return -ENOMEM;
 
134
 
 
135
        if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev)))
 
136
                goto finish;
 
137
 
 
138
        if ((read_only = udev_device_get_sysattr_value(udev_device, "ro")))
 
139
                if ((b = streq(read_only, "1")))
 
140
                        goto finish;
 
141
 
 
142
finish:
 
143
        if (udev_device)
 
144
                udev_device_unref(udev_device);
 
145
 
 
146
        if (udev)
 
147
                udev_unref(udev);
 
148
 
 
149
        return b;
 
150
}
 
151
 
 
152
bool enough_ram(void) {
 
153
        struct sysinfo si;
 
154
 
 
155
        assert_se(sysinfo(&si) >= 0);
 
156
 
 
157
        /* Enable readahead only with at least 128MB memory */
 
158
        return si.totalram > 127 * 1024*1024 / si.mem_unit;
 
159
}
 
160
 
 
161
int open_inotify(void) {
 
162
        int fd;
 
163
 
 
164
        if ((fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
 
165
                log_error("Failed to create inotify handle: %m");
 
166
                return -errno;
 
167
        }
 
168
 
 
169
        mkdir("/run/systemd", 0755);
 
170
        mkdir("/run/systemd/readahead", 0755);
 
171
 
 
172
        if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) {
 
173
                log_error("Failed to watch /run/systemd/readahead: %m");
 
174
                close_nointr_nofail(fd);
 
175
                return -errno;
 
176
        }
 
177
 
 
178
        return fd;
 
179
}
 
180
 
 
181
ReadaheadShared *shared_get(void) {
 
182
        int fd;
 
183
        ReadaheadShared *m = NULL;
 
184
 
 
185
        mkdir("/run/systemd", 0755);
 
186
        mkdir("/run/systemd/readahead", 0755);
 
187
 
 
188
        if ((fd = open("/run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) {
 
189
                log_error("Failed to create shared memory segment: %m");
 
190
                goto finish;
 
191
        }
 
192
 
 
193
        if (ftruncate(fd, sizeof(ReadaheadShared)) < 0) {
 
194
                log_error("Failed to truncate shared memory segment: %m");
 
195
                goto finish;
 
196
        }
 
197
 
 
198
        if ((m = mmap(NULL, sizeof(ReadaheadShared), PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
 
199
                log_error("Failed to mmap shared memory segment: %m");
 
200
                m = NULL;
 
201
                goto finish;
 
202
        }
 
203
 
 
204
finish:
 
205
        if (fd >= 0)
 
206
                close_nointr_nofail(fd);
 
207
 
 
208
        return m;
 
209
}
 
210
 
 
211
#define BUMP_REQUEST_NR (16*1024)
 
212
 
 
213
int bump_request_nr(const char *p) {
 
214
        struct stat st;
 
215
        uint64_t u;
 
216
        char *ap = NULL, *line = NULL;
 
217
        int r;
 
218
        dev_t d;
 
219
 
 
220
        assert(p);
 
221
 
 
222
        if (stat(p, &st) < 0)
 
223
                return -errno;
 
224
 
 
225
        if (major(st.st_dev) == 0)
 
226
                return 0;
 
227
 
 
228
        d = st.st_dev;
 
229
        block_get_whole_disk(d, &d);
 
230
 
 
231
        if (asprintf(&ap, "/sys/dev/block/%u:%u/queue/nr_requests", major(d), minor(d)) < 0) {
 
232
                r= -ENOMEM;
 
233
                goto finish;
 
234
        }
 
235
 
 
236
        r = read_one_line_file(ap, &line);
 
237
        if (r < 0) {
 
238
                if (r == -ENOENT)
 
239
                        r = 0;
 
240
                goto finish;
 
241
        }
 
242
 
 
243
        r = safe_atou64(line, &u);
 
244
        if (r >= 0 && u >= BUMP_REQUEST_NR) {
 
245
                r = 0;
 
246
                goto finish;
 
247
        }
 
248
 
 
249
        free(line);
 
250
        line = NULL;
 
251
 
 
252
        if (asprintf(&line, "%lu", (unsigned long) BUMP_REQUEST_NR) < 0) {
 
253
                r = -ENOMEM;
 
254
                goto finish;
 
255
        }
 
256
 
 
257
        r = write_one_line_file(ap, line);
 
258
        if (r < 0)
 
259
                goto finish;
 
260
 
 
261
        log_info("Bumped block_nr parameter of %u:%u to %lu. This is a temporary hack and should be removed one day.", major(d), minor(d), (unsigned long) BUMP_REQUEST_NR);
 
262
        r = 1;
 
263
 
 
264
finish:
 
265
        free(ap);
 
266
        free(line);
 
267
 
 
268
        return r;
 
269
}