From 54a1656271755143c875214f00897d266735c10e Mon Sep 17 00:00:00 2001 From: Dave Eddy Date: Sat, 18 Aug 2018 21:48:45 -0400 Subject: [PATCH] OS-7147 consolidate disk_size and removable_disk into disklist --- src/Makefile | 12 +-- src/disk_size.c | 56 ----------- src/disklist.c | 220 +++++++++++++++++++++++++++++++++++++++++++ src/manifest | 2 - src/removable_disk.c | 48 ---------- 5 files changed, 223 insertions(+), 115 deletions(-) delete mode 100644 src/disk_size.c create mode 100644 src/disklist.c delete mode 100644 src/removable_disk.c diff --git a/src/Makefile b/src/Makefile index eb0c4abf0..eee1d5c59 100644 --- a/src/Makefile +++ b/src/Makefile @@ -127,11 +127,10 @@ JS_CHECK_OLDSKOOL_TARGETS = \ C_CHECK_TARGETS=\ bootparams.c \ cryptpass.c \ - disk_size.c \ + disklist.c \ measure_terminal.c \ nomknod.c \ qemu-exec.c \ - removable_disk.c \ vmunbundle.c \ zfs_recv.c \ zfs_send.c \ @@ -279,9 +278,7 @@ TARGETS = \ bootparams \ disklayout \ disklist \ - disk_size \ mkzpool \ - removable_disk \ vmunbundle \ zfs_recv \ zfs_send \ @@ -330,13 +327,14 @@ $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(SUBDIRS_ENV) $(TARGET) -all: $(TARGETS) $(USR_LIB_TARGETS) sysinfo nictagadm sysevent \ +all: $(TARGETS) $(USR_LIB_TARGETS) sysinfo nictagadm sysevent disklist \ $(SMARTDC_TARGETS) $(SMARTDC_LIB_TARGETS) $(SUBDIRS) install: all $(SUBDIRS) mkdir -p $(DESTDIR)/usr/bin cp -p $(TARGETS) sysinfo nictagadm $(DESTDIR)/usr/bin mkdir -p $(DESTDIR)/usr/sbin + cp -p disklist $(DESTDIR)/usr/bin cp -p sysevent $(DESTDIR)/usr/sbin cp -p $(USR_LIB_TARGETS) $(DESTDIR)/usr/lib mkdir -p $(DESTDIR)/smartdc/bin @@ -505,10 +503,6 @@ disklayout: disklayout.js cp disklayout.js disklayout chmod 0755 disklayout -disklist: disklist.sh - cp disklist.sh disklist - chmod 0755 disklist - mkzpool: mkzpool.js cp mkzpool.js mkzpool chmod 0755 mkzpool diff --git a/src/disk_size.c b/src/disk_size.c deleted file mode 100644 index 3d9f51670..000000000 --- a/src/disk_size.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010 Joyent Inc., All rights reserved. - * - * This tool takes the character device node for a disk and prints the size - * in *bytes* for that disk. On any error, a message explaining the problem - * is printed to STDERR and the exit code is non-zero. - * - */ - - -#include -#include -#include -#include -#include -#include -#include - -void -usage(char *argv0) -{ - printf("Usage: %s [char dev]\n", argv0); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - char *devpath = argv[1]; - int devnode; - int ret; - unsigned long long bytes; - struct dk_minfo mediainfo; - - if (argc != 2) { - fprintf(stderr, "FATAL: Device argument required\n"); - usage(argv[0]); - } - - if ((devnode = open(devpath, O_RDONLY)) < 0) { - fprintf(stderr, "FATAL: Could not open %s\n", devpath); - usage(argv[0]); - } - - ret = ioctl(devnode, DKIOCGMEDIAINFO, &mediainfo); - close(devnode); - - if (ret < 0) { - fprintf(stderr, "FATAL: DKIOCGMEDIAINFO failed\n"); - exit(1); - } - - bytes = (mediainfo.dki_capacity * mediainfo.dki_lbsize); - printf("%llu\n", bytes); - exit(0); -} diff --git a/src/disklist.c b/src/disklist.c new file mode 100644 index 000000000..ce19a9952 --- /dev/null +++ b/src/disklist.c @@ -0,0 +1,220 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at http://smartos.org/CDDL + * + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file. + * + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2018 Joyent, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define verbose_warn(...) \ + do { \ + if (is_verbose) { \ + warn(__VA_ARGS__); \ + } \ + } while (0) + +char mode = '0'; +boolean_t is_verbose = B_FALSE; +boolean_t printed_disk = B_FALSE; + +/* + * Print the usage message to the given FILE handle + */ +static void +usage(FILE *s) +{ + fprintf(s, "usage: disklist [-ahnrv]\n"); + fprintf(s, "\n"); + fprintf(s, "list the disks on the system\n"); + fprintf(s, "\n"); + fprintf(s, "options\n"); + fprintf(s, " -a list all devices\n"); + fprintf(s, " -h print this message and exit\n"); + fprintf(s, " -n list non-removable devices\n"); + fprintf(s, " -r list removable devices\n"); + fprintf(s, " -v verbose output\n"); +} + +/* + * Process a single disk. To maintain consistency with the original disklist.sh + * script, this function will ignore and not print any disks that encounter any + * failures (such as failing to open, failing to ioctl, etc.). However, `-v` + * can be specified to print debug messages to stderr with information about any + * failures encountered. + */ +void do_disk(char *dsk_path) { + char dsk_name[PATH_MAX]; + char rdsk_path[PATH_MAX]; + int devnode; + int removable; + int ret; + struct stat buf; + int len = strlen(dsk_path); + + if (len < 2) { + return; + } + + // Only care about files that end in "s2" + if (strcmp(dsk_path + len - 2, "s2") != 0) { + return; + } + + strncpy(dsk_name, dsk_path, len - 2); + dsk_name[len - 2] = '\0'; + + if (snprintf(rdsk_path, PATH_MAX, "/dev/rdsk/%sp0", dsk_name) <= 0) { + err(2, "snprintf"); + }; + + if ((devnode = open(rdsk_path, O_RDONLY)) < 0) { + verbose_warn("open %s", rdsk_path); + return; + } + + if (fstat(devnode, &buf) == -1 || !S_ISCHR(buf.st_mode)) { + verbose_warn("%s: not a character device", rdsk_path); + goto done; + } + + ret = ioctl(devnode, DKIOCREMOVABLE, &removable); + if (ret < 0) { + verbose_warn("ioctl DKIOCREMOVABLE %s", rdsk_path); + goto done; + } + + /* + * Print only non-removable disks and their sizes - this is an + * undocumented flag for this program with a very specific purpose + * (currently only used by the sysinfo command). + */ + if (mode == 's') { + unsigned long long bytes; + struct dk_minfo mediainfo; + + if (removable) { + goto done; + } + + ret = ioctl(devnode, DKIOCGMEDIAINFO, &mediainfo); + if (ret < 0) { + verbose_warn("ioctl DKIOCGMEDIAINFO %s", rdsk_path); + goto done; + } + + bytes = mediainfo.dki_capacity * mediainfo.dki_lbsize; + + printf("%s=%llu\n", dsk_name, bytes); + + goto done; + } + + if ((mode == 'a') || + (mode == 'r' && removable) || + (mode == 'n' && !removable)) { + + if (printed_disk) { + printf(" %s", dsk_name); + } else { + printf("%s", dsk_name); + } + + printed_disk = B_TRUE; + } + +done: + close(devnode); +} + +int main(int argc, char **argv) { + DIR *d; + struct dirent *dp; + int opt; + + while ((opt = getopt(argc, argv, "ahnrsv")) != -1) { + switch (opt) { + case 'a': + mode = 'a'; + break; + case 'h': + usage(stdout); + return (0); + case 'n': + mode = 'n'; + break; + case 'r': + mode = 'r'; + break; + case 's': + mode = 's'; + break; + case 'v': + is_verbose = B_TRUE; + break; + default: + usage(stderr); + return (1); + } + } + argc -= optind; + argv += optind; + + /* + * This is to mimic the behavior of the disklist.sh script that came + * before this program. If no "mode" argument is specified on the + * command line, print nothing and exit 0. + */ + if (mode == '0') { + return (0); + } + + d = opendir("/dev/dsk"); + if (d == NULL) { + err(1, "opendir /dev/dsk"); + } + + while ((dp = readdir(d)) != NULL) { + do_disk(dp->d_name); + } + + if ((mode == 'a' || mode == 'n' || mode == 'r') && printed_disk) { + printf("\n"); + } + + closedir(d); + return (0); +} diff --git a/src/manifest b/src/manifest index 05bb95a7b..cec5f8f78 100644 --- a/src/manifest +++ b/src/manifest @@ -1028,8 +1028,6 @@ f usr/bin/sysinfo 0555 root bin f usr/bin/bootparams 0555 root bin f usr/bin/disklayout 0555 root bin f usr/bin/disklist 0555 root bin -f usr/bin/disk_size 0555 root bin -f usr/bin/removable_disk 0555 root bin f usr/bin/mkzpool 0555 root bin f usr/lib/cryptpass 0555 root bin f usr/lib/measure_terminal 0555 root bin diff --git a/src/removable_disk.c b/src/removable_disk.c deleted file mode 100644 index 8f75b5f9c..000000000 --- a/src/removable_disk.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void -usage(char *argv0) { - printf("Usage: %s [char dev]\n", argv0); -} - -int -main(int argc, char *argv[]) { - char *devpath = argv[1]; - int devnode; - struct stat buf; - int ret; - int removable; - - if (argc != 2) { - usage(argv[0]); - return (-1); - } - - if ((devnode = open(devpath, O_RDONLY)) < 0) { - printf("Could not open %s\n", devpath); - usage(argv[0]); - return (-1); - } - - if (fstat(devnode, &buf) == -1 || !S_ISCHR(buf.st_mode)) { - printf("%s: not a character device\n", devpath); - usage(argv[0]); - close(devnode); - return (-1); - } - - ret = ioctl(devnode, DKIOCREMOVABLE, &removable); - - if ((ret >= 0) && (removable != 0)) { - close(devnode); - return (0); - } - - close(devnode); - return (1); -}