diff options
Diffstat (limited to 'usr/src/cmd/lofiadm/main.c')
-rw-r--r-- | usr/src/cmd/lofiadm/main.c | 160 |
1 files changed, 114 insertions, 46 deletions
diff --git a/usr/src/cmd/lofiadm/main.c b/usr/src/cmd/lofiadm/main.c index d41ceaead3..87c6435386 100644 --- a/usr/src/cmd/lofiadm/main.c +++ b/usr/src/cmd/lofiadm/main.c @@ -59,6 +59,8 @@ #include <cryptoutil.h> #include <sys/crypto/ioctl.h> #include <sys/crypto/ioctladmin.h> +#include <sys/cmlb.h> +#include <sys/mkdev.h> #include "utils.h" #include <LzmaEnc.h> @@ -68,7 +70,7 @@ #include <blowfish/blowfish_impl.h> static const char USAGE[] = - "Usage: %s [-r] -a file [ device ]\n" + "Usage: %s [-r] [-l] -a file [ device ]\n" " %s [-r] -c crypto_algorithm -a file [device]\n" " %s [-r] -c crypto_algorithm -k raw_key_file -a file [device]\n" " %s [-r] -c crypto_algorithm -T [token]:[manuf]:[serial]:key " @@ -218,7 +220,7 @@ static ISzAlloc g_Alloc = { /*ARGSUSED*/ static int lzma_compress(void *src, size_t srclen, void *dst, - size_t *dstlen, int level) + size_t *dstlen, int level) { CLzmaEncProps props; size_t outsize2; @@ -280,14 +282,30 @@ lzma_compress(void *src, size_t srclen, void *dst, static int name_to_minor(const char *devicename) { - int minor; + struct stat st; + + /* + * If devicename does not exist, then devicename contains + * the name of the device to be created. + * Note we only allow non-labeled devices here. + */ + if (stat(devicename, &st)) { + int minor, rv; - if (sscanf(devicename, "/dev/" LOFI_BLOCK_NAME "/%d", &minor) == 1) { - return (minor); + rv = sscanf(devicename, "/dev/" LOFI_BLOCK_NAME "/%d", &minor); + if (rv == 1) + return (minor); + rv = sscanf(devicename, "/dev/" LOFI_CHAR_NAME "/%d", &minor); + if (rv == 1) + return (minor); + + return (0); } - if (sscanf(devicename, "/dev/" LOFI_CHAR_NAME "/%d", &minor) == 1) { - return (minor); + + if (st.st_mode & S_IFCHR || st.st_mode & S_IFBLK) { + return (LOFI_MINOR2ID(minor(st.st_rdev))); } + return (0); } @@ -303,7 +321,32 @@ static int sleeptime = 2; /* number of seconds to sleep between stat's */ static int maxsleep = 120; /* maximum number of seconds to sleep */ static void -wait_until_dev_complete(int minor) +make_blkdevname(struct lofi_ioctl *li, char *path, size_t len) +{ + char *r1, *r2; + size_t l1; + + if (li->li_devpath[0] == '\0') { + if (li->li_labeled) + (void) strlcpy(path, "unknown", len); + else + (void) snprintf(path, len, + "/dev/" LOFI_BLOCK_NAME "/%d", li->li_id); + return; + } + (void) strlcpy(path, li->li_devpath, len); + r1 = strchr(path, 'r'); + l1 = r1 - path; + r2 = strchr(li->li_devpath, 'r'); + (void) strlcpy(r1, r2+1, len - l1); + + if (li->li_labeled) { + (void) strlcat(path, "p0", len); + } +} + +static void +wait_until_dev_complete(struct lofi_ioctl *li) { struct stat64 buf; int cursleep; @@ -311,10 +354,12 @@ wait_until_dev_complete(int minor) char charpath[MAXPATHLEN]; di_devlink_handle_t hdl; - (void) snprintf(blkpath, sizeof (blkpath), "/dev/%s/%d", - LOFI_BLOCK_NAME, minor); - (void) snprintf(charpath, sizeof (charpath), "/dev/%s/%d", - LOFI_CHAR_NAME, minor); + make_blkdevname(li, blkpath, sizeof (blkpath)); + (void) strlcpy(charpath, li->li_devpath, sizeof (charpath)); + + if (li->li_labeled) { + (void) strlcat(charpath, "p0", sizeof (charpath)); + } /* Check if links already present */ if (stat64(blkpath, &buf) == 0 && stat64(charpath, &buf) == 0) @@ -352,14 +397,14 @@ out: * DO NOT use this function if the filename is actually the device name. */ static int -lofi_map_file(int lfd, struct lofi_ioctl li, const char *filename, +lofi_map_file(int lfd, struct lofi_ioctl *li, const char *filename, boolean_t no_devlink_flag) { int minor; - li.li_minor = 0; - (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename)); - minor = ioctl(lfd, LOFI_MAP_FILE, &li); + li->li_id = 0; + (void) strlcpy(li->li_filename, filename, sizeof (li->li_filename)); + minor = ioctl(lfd, LOFI_MAP_FILE, li); if (minor == -1) { if (errno == ENOTSUP) warn(gettext("encrypting compressed files is " @@ -367,7 +412,7 @@ lofi_map_file(int lfd, struct lofi_ioctl li, const char *filename, die(gettext("could not map file %s"), filename); } if (!no_devlink_flag) - wait_until_dev_complete(minor); + wait_until_dev_complete(li); return (minor); } @@ -377,12 +422,14 @@ lofi_map_file(int lfd, struct lofi_ioctl li, const char *filename, */ static void add_mapping(int lfd, const char *devicename, const char *filename, - mech_alias_t *cipher, const char *rkey, size_t rksz, - boolean_t rdonly, boolean_t no_devlink_flag) + mech_alias_t *cipher, const char *rkey, size_t rksz, boolean_t rdonly, + boolean_t label, boolean_t no_devlink_flag) { struct lofi_ioctl li; + bzero(&li, sizeof (li)); li.li_readonly = rdonly; + li.li_labeled = label; li.li_crypto_enabled = B_FALSE; if (cipher != NULL) { @@ -412,17 +459,22 @@ add_mapping(int lfd, const char *devicename, const char *filename, if (devicename == NULL) { int minor; + char path[MAXPATHLEN]; /* pick one via the driver */ - minor = lofi_map_file(lfd, li, filename, no_devlink_flag); - /* if mapping succeeds, print the one picked */ - (void) printf("/dev/%s/%d\n", LOFI_BLOCK_NAME, minor); + minor = lofi_map_file(lfd, &li, filename, no_devlink_flag); + if (minor > 0) { + make_blkdevname(&li, path, sizeof (path)); + + /* if mapping succeeds, print the one picked */ + (void) printf("%s\n", path); + } return; } /* use device we were given */ - li.li_minor = name_to_minor(devicename); - if (li.li_minor == 0) { + li.li_id = name_to_minor(devicename); + if (li.li_id == 0) { die(gettext("malformed device name %s\n"), devicename); } (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename)); @@ -436,7 +488,7 @@ add_mapping(int lfd, const char *devicename, const char *filename, devicename); } if (!no_devlink_flag) - wait_until_dev_complete(li.li_minor); + wait_until_dev_complete(&li); } /* @@ -456,7 +508,7 @@ delete_mapping(int lfd, const char *devicename, const char *filename, /* delete by filename */ (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename)); - li.li_minor = 0; + li.li_id = 0; if (ioctl(lfd, LOFI_UNMAP_FILE, &li) == -1) { die(gettext("could not unmap file %s"), filename); } @@ -464,8 +516,8 @@ delete_mapping(int lfd, const char *devicename, const char *filename, } /* delete by device */ - li.li_minor = name_to_minor(devicename); - if (li.li_minor == 0) { + li.li_id = name_to_minor(devicename); + if (li.li_id == 0) { die(gettext("malformed device name %s\n"), devicename); } if (ioctl(lfd, LOFI_UNMAP_FILE_MINOR, &li) == -1) { @@ -480,22 +532,24 @@ static void print_one_mapping(int lfd, const char *devicename, const char *filename) { struct lofi_ioctl li; + char blkpath[MAXPATHLEN]; if (devicename == NULL) { /* given filename, print devicename */ - li.li_minor = 0; + li.li_id = 0; (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename)); if (ioctl(lfd, LOFI_GET_MINOR, &li) == -1) { die(gettext("could not find device for %s"), filename); } - (void) printf("/dev/%s/%d\n", LOFI_BLOCK_NAME, li.li_minor); + make_blkdevname(&li, blkpath, sizeof (blkpath)); + (void) printf("%s\n", blkpath); return; } /* given devicename, print filename */ - li.li_minor = name_to_minor(devicename); - if (li.li_minor == 0) { + li.li_id = name_to_minor(devicename); + if (li.li_id == 0) { die(gettext("malformed device name %s\n"), devicename); } if (ioctl(lfd, LOFI_GET_FILENAME, &li) == -1) { @@ -516,24 +570,23 @@ print_mappings(int fd) char path[MAXPATHLEN]; char options[MAXPATHLEN] = { 0 }; - li.li_minor = 0; + li.li_id = 0; if (ioctl(fd, LOFI_GET_MAXMINOR, &li) == -1) { die("ioctl"); } - maxminor = li.li_minor; + maxminor = li.li_id; (void) printf(FORMAT, gettext("Block Device"), gettext("File"), gettext("Options")); for (minor = 1; minor <= maxminor; minor++) { - li.li_minor = minor; + li.li_id = minor; if (ioctl(fd, LOFI_GET_FILENAME, &li) == -1) { if (errno == ENXIO) continue; warn("ioctl"); break; } - (void) snprintf(path, sizeof (path), "/dev/%s/%d", - LOFI_BLOCK_NAME, minor); + make_blkdevname(&li, path, sizeof (path)); options[0] = '\0'; @@ -548,14 +601,22 @@ print_mappings(int fd) gettext("Compressed(%s)"), li.li_algorithm); if (li.li_readonly) { if (strlen(options) != 0) { - (void) strlcat(options, ",", sizeof (options)); - (void) strlcat(options, "Readonly", + (void) strlcat(options, ",Readonly", sizeof (options)); } else { (void) snprintf(options, sizeof (options), gettext("Readonly")); } } + if (li.li_labeled) { + if (strlen(options) != 0) { + (void) strlcat(options, ",Labeled", + sizeof (options)); + } else { + (void) snprintf(options, sizeof (options), + gettext("Labeled")); + } + } if (strlen(options) == 0) (void) snprintf(options, sizeof (options), "-"); @@ -1308,7 +1369,7 @@ lofi_uncompress(int lfd, const char *filename) * already mapped. */ li.li_crypto_enabled = B_FALSE; - li.li_minor = 0; + li.li_id = 0; (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename)); if (ioctl(lfd, LOFI_GET_MINOR, &li) != -1) die(gettext("%s must be unmapped before uncompressing"), @@ -1320,7 +1381,7 @@ lofi_uncompress(int lfd, const char *filename) if (statbuf.st_size == 0) return; - minor = lofi_map_file(lfd, li, filename, B_FALSE); + minor = lofi_map_file(lfd, &li, filename, B_FALSE); (void) snprintf(devicename, sizeof (devicename), "/dev/%s/%d", LOFI_BLOCK_NAME, minor); @@ -1432,7 +1493,7 @@ lofi_compress(int *lfd, const char *filename, int compress_index, * Disallow compressing the file if it is * already mapped */ - lic.li_minor = 0; + lic.li_id = 0; (void) strlcpy(lic.li_filename, filename, sizeof (lic.li_filename)); if (ioctl(*lfd, LOFI_GET_MINOR, &lic) != -1) die(gettext("%s must be unmapped before compressing"), @@ -1849,13 +1910,14 @@ main(int argc, char *argv[]) const char *algname = COMPRESS_ALGORITHM; int openflag; int minor; - int compress_index; + int compress_index; uint32_t segsize = SEGSIZE; static char *lofictl = "/dev/" LOFI_CTL_NAME; boolean_t force = B_FALSE; const char *pname; boolean_t errflag = B_FALSE; boolean_t addflag = B_FALSE; + boolean_t labelflag = B_FALSE; boolean_t rdflag = B_FALSE; boolean_t deleteflag = B_FALSE; boolean_t ephflag = B_FALSE; @@ -1877,7 +1939,7 @@ main(int argc, char *argv[]) (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); - while ((c = getopt(argc, argv, "a:c:Cd:efk:rs:T:UX")) != EOF) { + while ((c = getopt(argc, argv, "a:c:Cd:efk:lrs:T:UX")) != EOF) { switch (c) { case 'a': addflag = B_TRUE; @@ -1932,6 +1994,9 @@ main(int argc, char *argv[]) need_crypto = B_TRUE; cipher_only = B_FALSE; /* need to unset cipher_only */ break; + case 'l': + labelflag = B_TRUE; + break; case 'r': rdflag = B_TRUE; break; @@ -1972,9 +2037,12 @@ main(int argc, char *argv[]) /* Check for mutually exclusive combinations of options */ if (errflag || (addflag && deleteflag) || + (labelflag && !addflag) || (rdflag && !addflag) || (!addflag && need_crypto) || - ((compressflag || uncompressflag) && (addflag || deleteflag))) + (need_crypto && labelflag) || + ((compressflag || uncompressflag) && + (labelflag || addflag || deleteflag))) usage(pname); /* ephemeral key, and key from either file or token are incompatible */ @@ -2091,7 +2159,7 @@ main(int argc, char *argv[]) */ if (addflag) add_mapping(lfd, devicename, filename, cipher, rkey, rksz, - rdflag, no_devlink_flag); + rdflag, labelflag, no_devlink_flag); else if (compressflag) lofi_compress(&lfd, filename, compress_index, segsize); else if (uncompressflag) |