📄 dmutils.c
字号:
/* * device-mapper utilities for cryptmount * $Revision: 117 $, $Date: 2006-07-30 10:20:45 +0100 (Sun, 30 Jul 2006) $ * Copyright 2005, RW Penney *//* This file is part of cryptmount cryptmount is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exemption, permission is granted to link cryptmount with the OpenSSL project's "OpenSSL" library and distribute the linked code without invoking clause 2(b) of the GNU GPL version 2. cryptmount is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cryptmount; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#if defined(HAVE_LIBDEVMAP)# include <libdevmapper.h>#else# error libdevmapper headers are needed to build cryptmount#endif#include "cryptmount.h"#include "dmutils.h"struct dm_task *devmap_prepare(int type, const char *ident) /* prepare device-mapper task structure */{ struct dm_task *dmt=NULL; dmt = dm_task_create(type); if (dmt != NULL) { if (!dm_task_set_name(dmt, ident)) { dm_task_destroy(dmt); dmt = NULL; } } return dmt;}int devmap_path(char **buff, const char *ident) /* create device-mapper full pathname from target description */{ size_t pfxlen, sfxlen; pfxlen = strlen(dm_dir()); sfxlen = strlen(ident); *buff = (char*)realloc((void*)(*buff), (pfxlen + sfxlen + 2)); snprintf(*buff, (pfxlen + sfxlen + 2), "%s/%s", dm_dir(), ident); return (int)(pfxlen + sfxlen + 1);}int devmap_create(const char *ident, uint64_t blk0, uint64_t blklen, const char *tgttype, const char *params) /* create new device-mapper target & associated device node: */{ struct dm_task *dmt=NULL; struct dm_info dmi; char *devpath=NULL; struct stat sbuff; mode_t mode; dev_t dev; /* create device-mapper target: */ if ((dmt = devmap_prepare(DM_DEVICE_CREATE, ident)) == NULL) { fprintf(stderr, "failed to initialize device-mapper task\n"); return ERR_DMSETUP; } if (!dm_task_add_target(dmt, blk0, blklen, tgttype, params)) { fprintf(stderr, "failed to add device-mapper target \"%s\" { %s }\n", tgttype, params); return ERR_DMSETUP; } if (!dm_task_run(dmt)) { fprintf(stderr, "device-mapper task failed\n"); return ERR_DMSETUP; } if (!dm_task_get_info(dmt, &dmi)) { fprintf(stderr, "device-mapper info not available\n"); return ERR_DMSETUP; } dm_task_destroy(dmt); /* create device node (below /dev?): */ mode = S_IFBLK | S_IRUSR | S_IWUSR; dev = makedev(dmi.major, dmi.minor); devmap_path(&devpath, ident); if (stat(devpath, &sbuff) != 0 && mknod(devpath, mode, dev) != 0) { fprintf(stderr, "device \"%s\" (%u,%u) creation failed\n", devpath, dmi.major, dmi.minor); return ERR_BADDEVICE; } if (devpath != NULL) free((void*)devpath); return ERR_NOERROR;}int devmap_dependencies(const char *ident, unsigned *count, dev_t **devids){ struct dm_task *dmt=NULL; struct dm_deps *deps; unsigned i; int eflag=ERR_NOERROR; if ((dmt = devmap_prepare(DM_DEVICE_DEPS, ident)) == NULL) { fprintf(stderr, "failed to initialize device-mapper task\n"); eflag = ERR_DMSETUP; goto bail_out; } if (!dm_task_run(dmt)) { fprintf(stderr, "device-mapper task failed\n"); eflag = ERR_DMSETUP; goto bail_out; } if ((deps = dm_task_get_deps(dmt)) == NULL) { eflag = ERR_DMSETUP; goto bail_out; } /* copy device info into fresh array: */ *count = deps->count; *devids = (dev_t*)malloc((size_t)(deps->count * sizeof(dev_t))); for (i=0; i<deps->count; ++i) (*devids)[i] = (dev_t)deps->device[i]; bail_out: if (dmt != NULL) dm_task_destroy(dmt); return eflag;}int devmap_remove(const char *ident) /* remove device-mapper target and associated device */{ struct dm_task *dmt=NULL; struct dm_info dmi; struct stat sbuff; char *devpath=NULL; int eflag = ERR_NOERROR; /* check device-mapper target is configured & get info: */ if (!is_configured(ident, &dmi)) { eflag = ERR_BADDEVICE; goto bail_out; } /* remove device node (below /dev?): */ devmap_path(&devpath, ident); if (stat(devpath, &sbuff) != 0) { fprintf(stderr, "unable to stat() device node\n"); eflag = ERR_DMSETUP; goto bail_out; } if ((uint32_t)major(sbuff.st_rdev) == dmi.major && (uint32_t)minor(sbuff.st_rdev) == dmi.minor) { unlink(devpath); } else { fprintf(stderr,"device \"%s\" doesn't match device-mapper info (%d,%d)\n", devpath, dmi.major, dmi.minor); eflag = ERR_BADDEVICE; goto bail_out; } /* remove device-mapper target: */ if ((dmt = devmap_prepare(DM_DEVICE_REMOVE, ident)) == NULL) { fprintf(stderr, "failed to initialize device-mapper task\n"); eflag = ERR_DMSETUP; goto bail_out; } if (!dm_task_run(dmt)) { fprintf(stderr, "device-mapper task failed\n"); eflag = ERR_DMSETUP; goto bail_out; } bail_out: if (dmt != NULL) dm_task_destroy(dmt); if (devpath != NULL) free((void*)devpath); return ERR_NOERROR;}int is_configured(const char *ident, struct dm_info *dminfo) /* check if device-mapper target has been setup & (optionally) get info */{ struct dm_task *dmt=NULL; struct dm_info *dmi, dmi_local; int config=1; dmi = (dminfo != NULL ? dminfo : &dmi_local); /* create device-mapper target: */ if (ident == NULL || (dmt = devmap_prepare(DM_DEVICE_INFO, ident)) == NULL || !dm_task_run(dmt) || !dm_task_get_info(dmt, dmi)) { config = 0; } if (dmt != NULL) dm_task_destroy(dmt); return config;}/* * (C)Copyright 2005-2006, RW Penney */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -