blob: 4c2f24707af7eee537c3fbdbdb486f91558ae95e [file] [log] [blame]
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ken Sumrallc1bf8962012-01-06 19:09:42 -080017#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21#include <fcntl.h>
22#include <ctype.h>
23#include <sys/mount.h>
24#include <sys/stat.h>
25#include <errno.h>
26#include <sys/types.h>
27#include <sys/wait.h>
28#include <libgen.h>
29#include <time.h>
Ken Sumrall5bc31a22013-07-08 19:11:55 -070030#include <sys/swap.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080031
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080032#include <linux/loop.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080033#include <private/android_filesystem_config.h>
34#include <cutils/partition_utils.h>
35#include <cutils/properties.h>
Ken Sumrallbf021b42013-03-19 19:38:44 -070036#include <logwrap/logwrap.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080037
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080038#include "mincrypt/rsa.h"
39#include "mincrypt/sha.h"
40#include "mincrypt/sha256.h"
41
Ken Sumrallc1bf8962012-01-06 19:09:42 -080042#include "fs_mgr_priv.h"
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080043#include "fs_mgr_priv_verity.h"
Ken Sumrallc1bf8962012-01-06 19:09:42 -080044
45#define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
46#define KEY_IN_FOOTER "footer"
47
48#define E2FSCK_BIN "/system/bin/e2fsck"
Ken Sumrall5bc31a22013-07-08 19:11:55 -070049#define MKSWAP_BIN "/system/bin/mkswap"
50
Ken Sumrall4eaf9052013-09-18 17:49:21 -070051#define FSCK_LOG_FILE "/dev/fscklogs/log"
52
Ken Sumrall5bc31a22013-07-08 19:11:55 -070053#define ZRAM_CONF_DEV "/sys/block/zram0/disksize"
Ken Sumrallc1bf8962012-01-06 19:09:42 -080054
Ken Sumrallbf021b42013-03-19 19:38:44 -070055#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
56
Ken Sumrallc1bf8962012-01-06 19:09:42 -080057/*
58 * gettime() - returns the time in seconds of the system's monotonic clock or
59 * zero on error.
60 */
61static time_t gettime(void)
62{
63 struct timespec ts;
64 int ret;
65
66 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
67 if (ret < 0) {
68 ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
69 return 0;
70 }
71
72 return ts.tv_sec;
73}
74
75static int wait_for_file(const char *filename, int timeout)
76{
77 struct stat info;
78 time_t timeout_time = gettime() + timeout;
79 int ret = -1;
80
81 while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
82 usleep(10000);
83
84 return ret;
85}
86
Ken Sumrallab6b8522013-02-13 12:58:40 -080087static void check_fs(char *blk_device, char *fs_type, char *target)
Ken Sumrallc1bf8962012-01-06 19:09:42 -080088{
Ken Sumrallc1bf8962012-01-06 19:09:42 -080089 int status;
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -070090 int ret;
91 long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
92 char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro";
Ken Sumrallbf021b42013-03-19 19:38:44 -070093 char *e2fsck_argv[] = {
94 E2FSCK_BIN,
95 "-y",
96 blk_device
97 };
Ken Sumrallc1bf8962012-01-06 19:09:42 -080098
99 /* Check for the types of filesystems we know how to check */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800100 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700101 /*
102 * First try to mount and unmount the filesystem. We do this because
103 * the kernel is more efficient than e2fsck in running the journal and
104 * processing orphaned inodes, and on at least one device with a
105 * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
106 * to do what the kernel does in about a second.
107 *
108 * After mounting and unmounting the filesystem, run e2fsck, and if an
109 * error is recorded in the filesystem superblock, e2fsck will do a full
110 * check. Otherwise, it does nothing. If the kernel cannot mount the
111 * filesytsem due to an error, e2fsck is still run to do a full check
112 * fix the filesystem.
113 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800114 ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
115 if (!ret) {
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700116 umount(target);
117 }
118
Ken Sumrallab6b8522013-02-13 12:58:40 -0800119 INFO("Running %s on %s\n", E2FSCK_BIN, blk_device);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800120
Ken Sumrallbf021b42013-03-19 19:38:44 -0700121 ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
Ken Sumrall4eaf9052013-09-18 17:49:21 -0700122 &status, true, LOG_KLOG | LOG_FILE,
123 true, FSCK_LOG_FILE);
Ken Sumrallbf021b42013-03-19 19:38:44 -0700124
125 if (ret < 0) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800126 /* No need to check for error in fork, we can't really handle it now */
Ken Sumrallbf021b42013-03-19 19:38:44 -0700127 ERROR("Failed trying to run %s\n", E2FSCK_BIN);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800128 }
129 }
130
131 return;
132}
133
134static void remove_trailing_slashes(char *n)
135{
136 int len;
137
138 len = strlen(n) - 1;
139 while ((*(n + len) == '/') && len) {
140 *(n + len) = '\0';
141 len--;
142 }
143}
144
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700145/*
146 * Mark the given block device as read-only, using the BLKROSET ioctl.
147 * Return 0 on success, and -1 on error.
148 */
149static void fs_set_blk_ro(const char *blockdev)
150{
151 int fd;
152 int ON = 1;
153
154 fd = open(blockdev, O_RDONLY);
155 if (fd < 0) {
156 // should never happen
157 return;
158 }
159
160 ioctl(fd, BLKROSET, &ON);
161 close(fd);
162}
163
164/*
165 * __mount(): wrapper around the mount() system call which also
166 * sets the underlying block device to read-only if the mount is read-only.
167 * See "man 2 mount" for return values.
168 */
169static int __mount(const char *source, const char *target,
170 const char *filesystemtype, unsigned long mountflags,
171 const void *data)
172{
173 int ret = mount(source, target, filesystemtype, mountflags, data);
174
175 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
176 fs_set_blk_ro(source);
177 }
178
179 return ret;
180}
181
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800182static int fs_match(char *in1, char *in2)
183{
184 char *n1;
185 char *n2;
186 int ret;
187
188 n1 = strdup(in1);
189 n2 = strdup(in2);
190
191 remove_trailing_slashes(n1);
192 remove_trailing_slashes(n2);
193
194 ret = !strcmp(n1, n2);
195
196 free(n1);
197 free(n2);
198
199 return ret;
200}
201
Ken Sumrallab6b8522013-02-13 12:58:40 -0800202int fs_mgr_mount_all(struct fstab *fstab)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800203{
204 int i = 0;
205 int encrypted = 0;
206 int ret = -1;
207 int mret;
William Roberts071f28a2014-01-14 14:33:44 -0500208 int mount_errno;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800209
Ken Sumrallab6b8522013-02-13 12:58:40 -0800210 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800211 return ret;
212 }
213
Ken Sumrallab6b8522013-02-13 12:58:40 -0800214 for (i = 0; i < fstab->num_entries; i++) {
215 /* Don't mount entries that are managed by vold */
Ken Sumrall6c2c1212013-02-22 17:36:21 -0800216 if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800217 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800218 }
219
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700220 /* Skip swap and raw partition entries such as boot, recovery, etc */
221 if (!strcmp(fstab->recs[i].fs_type, "swap") ||
222 !strcmp(fstab->recs[i].fs_type, "emmc") ||
Ken Sumrallab6b8522013-02-13 12:58:40 -0800223 !strcmp(fstab->recs[i].fs_type, "mtd")) {
224 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800225 }
226
Ken Sumrallab6b8522013-02-13 12:58:40 -0800227 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
228 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
229 }
230
231 if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
232 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
233 fstab->recs[i].mount_point);
234 }
235
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800236 if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) {
237 if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
238 ERROR("Could not set up verified partition, skipping!");
239 continue;
240 }
241 }
242
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700243 mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800244 fstab->recs[i].fs_type, fstab->recs[i].flags,
245 fstab->recs[i].fs_options);
246
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800247 if (!mret) {
248 /* Success! Go get the next one */
249 continue;
250 }
251
William Roberts071f28a2014-01-14 14:33:44 -0500252 /* back up errno as partition_wipe clobbers the value */
253 mount_errno = errno;
254
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800255 /* mount(2) returned an error, check if it's encrypted and deal with it */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800256 if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT) &&
257 !partition_wiped(fstab->recs[i].blk_device)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800258 /* Need to mount a tmpfs at this mountpoint for now, and set
259 * properties that vold will query later for decrypting
260 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800261 if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs",
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800262 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
William Roberts071f28a2014-01-14 14:33:44 -0500263 ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s error: %s\n",
264 fstab->recs[i].mount_point, strerror(errno));
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800265 goto out;
266 }
267 encrypted = 1;
268 } else {
William Roberts071f28a2014-01-14 14:33:44 -0500269 ERROR("Failed to mount an un-encryptable or wiped partition on"
270 "%s at %s options: %s error: %s\n",
271 fstab->recs[i].blk_device, fstab->recs[i].mount_point,
272 fstab->recs[i].fs_options, strerror(mount_errno));
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800273 goto out;
274 }
275 }
276
277 if (encrypted) {
278 ret = 1;
279 } else {
280 ret = 0;
281 }
282
283out:
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800284 return ret;
285}
286
Ken Sumrallab6b8522013-02-13 12:58:40 -0800287/* If tmp_mount_point is non-null, mount the filesystem there. This is for the
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800288 * tmp mount we do to check the user password
289 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800290int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
291 char *tmp_mount_point)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800292{
293 int i = 0;
294 int ret = -1;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800295 char *m;
296
Ken Sumrallab6b8522013-02-13 12:58:40 -0800297 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800298 return ret;
299 }
300
Ken Sumrallab6b8522013-02-13 12:58:40 -0800301 for (i = 0; i < fstab->num_entries; i++) {
302 if (!fs_match(fstab->recs[i].mount_point, n_name)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800303 continue;
304 }
305
306 /* We found our match */
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700307 /* If this swap or a raw partition, report an error */
308 if (!strcmp(fstab->recs[i].fs_type, "swap") ||
309 !strcmp(fstab->recs[i].fs_type, "emmc") ||
Ken Sumrallab6b8522013-02-13 12:58:40 -0800310 !strcmp(fstab->recs[i].fs_type, "mtd")) {
311 ERROR("Cannot mount filesystem of type %s on %s\n",
312 fstab->recs[i].fs_type, n_blk_device);
313 goto out;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800314 }
315
Ken Sumrallab6b8522013-02-13 12:58:40 -0800316 /* First check the filesystem if requested */
317 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
318 wait_for_file(n_blk_device, WAIT_TIMEOUT);
319 }
320
321 if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
322 check_fs(n_blk_device, fstab->recs[i].fs_type,
323 fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800324 }
325
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800326 if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) {
327 if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
328 ERROR("Could not set up verified partition, skipping!");
329 continue;
330 }
331 }
332
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800333 /* Now mount it where requested */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800334 if (tmp_mount_point) {
335 m = tmp_mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800336 } else {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800337 m = fstab->recs[i].mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800338 }
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700339 if (__mount(n_blk_device, m, fstab->recs[i].fs_type,
340 fstab->recs[i].flags, fstab->recs[i].fs_options)) {
William Roberts071f28a2014-01-14 14:33:44 -0500341 ERROR("Cannot mount filesystem on %s at %s options: %s error: %s\n",
342 n_blk_device, m, fstab->recs[i].fs_options, strerror(errno));
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800343 goto out;
344 } else {
345 ret = 0;
346 goto out;
347 }
348 }
349
350 /* We didn't find a match, say so and return an error */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800351 ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800352
353out:
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800354 return ret;
355}
356
357/*
358 * mount a tmpfs filesystem at the given point.
359 * return 0 on success, non-zero on failure.
360 */
361int fs_mgr_do_tmpfs_mount(char *n_name)
362{
363 int ret;
364
365 ret = mount("tmpfs", n_name, "tmpfs",
366 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
367 if (ret < 0) {
368 ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
369 return -1;
370 }
371
372 /* Success */
373 return 0;
374}
375
Ken Sumrallab6b8522013-02-13 12:58:40 -0800376int fs_mgr_unmount_all(struct fstab *fstab)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800377{
378 int i = 0;
379 int ret = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800380
Ken Sumrallab6b8522013-02-13 12:58:40 -0800381 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800382 return -1;
383 }
384
Ken Sumrallab6b8522013-02-13 12:58:40 -0800385 while (fstab->recs[i].blk_device) {
386 if (umount(fstab->recs[i].mount_point)) {
387 ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800388 ret = -1;
389 }
390 i++;
391 }
392
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800393 return ret;
394}
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700395
396/* This must be called after mount_all, because the mkswap command needs to be
397 * available.
398 */
399int fs_mgr_swapon_all(struct fstab *fstab)
400{
401 int i = 0;
402 int flags = 0;
403 int err = 0;
404 int ret = 0;
405 int status;
406 char *mkswap_argv[2] = {
407 MKSWAP_BIN,
408 NULL
409 };
410
411 if (!fstab) {
412 return -1;
413 }
414
415 for (i = 0; i < fstab->num_entries; i++) {
416 /* Skip non-swap entries */
417 if (strcmp(fstab->recs[i].fs_type, "swap")) {
418 continue;
419 }
420
421 if (fstab->recs[i].zram_size > 0) {
422 /* A zram_size was specified, so we need to configure the
423 * device. There is no point in having multiple zram devices
424 * on a system (all the memory comes from the same pool) so
425 * we can assume the device number is 0.
426 */
427 FILE *zram_fp;
428
429 zram_fp = fopen(ZRAM_CONF_DEV, "r+");
430 if (zram_fp == NULL) {
431 ERROR("Unable to open zram conf device " ZRAM_CONF_DEV);
432 ret = -1;
433 continue;
434 }
435 fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
436 fclose(zram_fp);
437 }
438
439 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
440 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
441 }
442
443 /* Initialize the swap area */
444 mkswap_argv[1] = fstab->recs[i].blk_device;
445 err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
Ken Sumrall4eaf9052013-09-18 17:49:21 -0700446 &status, true, LOG_KLOG, false, NULL);
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700447 if (err) {
448 ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
449 ret = -1;
450 continue;
451 }
452
453 /* If -1, then no priority was specified in fstab, so don't set
454 * SWAP_FLAG_PREFER or encode the priority */
455 if (fstab->recs[i].swap_prio >= 0) {
456 flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
457 SWAP_FLAG_PRIO_MASK;
458 flags |= SWAP_FLAG_PREFER;
459 } else {
460 flags = 0;
461 }
462 err = swapon(fstab->recs[i].blk_device, flags);
463 if (err) {
464 ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
465 ret = -1;
466 }
467 }
468
469 return ret;
470}
471
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800472/*
473 * key_loc must be at least PROPERTY_VALUE_MAX bytes long
474 *
Ken Sumrallab6b8522013-02-13 12:58:40 -0800475 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800476 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800477int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800478{
479 int i = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800480
Ken Sumrallab6b8522013-02-13 12:58:40 -0800481 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800482 return -1;
483 }
484 /* Initialize return values to null strings */
485 if (key_loc) {
486 *key_loc = '\0';
487 }
Ken Sumrallab6b8522013-02-13 12:58:40 -0800488 if (real_blk_device) {
489 *real_blk_device = '\0';
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800490 }
491
492 /* Look for the encryptable partition to find the data */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800493 for (i = 0; i < fstab->num_entries; i++) {
494 /* Don't deal with vold managed enryptable partitions here */
495 if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
496 continue;
497 }
498 if (!(fstab->recs[i].fs_mgr_flags & MF_CRYPT)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800499 continue;
500 }
501
502 /* We found a match */
503 if (key_loc) {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800504 strlcpy(key_loc, fstab->recs[i].key_loc, size);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800505 }
Ken Sumrallab6b8522013-02-13 12:58:40 -0800506 if (real_blk_device) {
507 strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800508 }
509 break;
510 }
511
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800512 return 0;
513}