Hello community, here is the log from the commit of package diskscan for openSUSE:Factory checked in at 2015-11-28 15:19:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/diskscan (Old) and /work/SRC/openSUSE:Factory/.diskscan.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "diskscan" Changes: -------- --- /work/SRC/openSUSE:Factory/diskscan/diskscan.changes 2015-11-16 18:51:32.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.diskscan.new/diskscan.changes 2015-11-28 15:19:19.000000000 +0100 @@ -1,0 +2,8 @@ +Thu Nov 26 13:18:40 UTC 2015 - mplus...@suse.com + +- Update to 0.19 + * When a partition is write mounted do not attempt to fix it as + it will mess the filesystem. + * Also fix building on Debian/kFreeBSD. + +------------------------------------------------------------------- Old: ---- 0.18.tar.gz New: ---- 0.19.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ diskscan.spec ++++++ --- /var/tmp/diff_new_pack.GPZFaw/_old 2015-11-28 15:19:19.000000000 +0100 +++ /var/tmp/diff_new_pack.GPZFaw/_new 2015-11-28 15:19:19.000000000 +0100 @@ -17,7 +17,7 @@ Name: diskscan -Version: 0.18 +Version: 0.19 Release: 0 Summary: Scan disk for bad or near failure sectors License: GPL-3.0+ ++++++ 0.18.tar.gz -> 0.19.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/CMakeLists.txt new/diskscan-0.19/CMakeLists.txt --- old/diskscan-0.18/CMakeLists.txt 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/CMakeLists.txt 2015-11-15 21:56:05.000000000 +0100 @@ -1,11 +1,16 @@ cmake_minimum_required(VERSION 3.0.2) project(diskscan - VERSION 0.18) + VERSION 0.19) export(PACKAGE diskscan) set(PACKAGE_VERSION ${PROJECT_VERSION}) +# Default to a debug build +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif(NOT CMAKE_BUILD_TYPE) + # Pull in zlib find_package(ZLIB REQUIRED) @@ -24,14 +29,18 @@ find_library(tinfo_LIBRARY NAMES tinfo curses) # Architecture files +message("SYSTEM NAME: ${CMAKE_SYSTEM_NAME}") if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(ARCH_SRC "arch/arch-linux.c") set(ARCH_INCLUDE "arch/arch-linux.h") +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD") + set(ARCH_SRC "arch/arch-freebsd.c") + set(ARCH_INCLUDE "arch/arch-posix.h") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") set(ARCH_SRC "arch/arch-freebsd.c") set(ARCH_INCLUDE "arch/arch-posix.h") else() - set(ARCH_SRC "arch/arch-posix.c") + set(ARCH_SRC "arch/arch-generic.c") set(ARCH_INCLUDE "arch/arch-posix.h") endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/DEVELOP.md new/diskscan-0.19/DEVELOP.md --- old/diskscan-0.18/DEVELOP.md 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/DEVELOP.md 2015-11-15 21:56:05.000000000 +0100 @@ -1,5 +1,11 @@ # Developing +## Debug build + +To create a debug build you can tell cmake: + + cmake -DCMAKE_BUILD_TYPE=DEBUG . + ## Updating Libraries Update libscsicmd: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/arch/arch-freebsd.c new/diskscan-0.19/arch/arch-freebsd.c --- old/diskscan-0.18/arch/arch-freebsd.c 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/arch/arch-freebsd.c 2015-11-15 21:56:05.000000000 +0100 @@ -3,6 +3,9 @@ #include <sys/disk.h> #include <sys/ioctl.h> #include <sys/types.h> +#include <sys/param.h> +#include <sys/ucred.h> +#include <sys/mount.h> #include "arch-posix.c" #include <net/if.h> @@ -33,6 +36,37 @@ return 0; } +disk_mount_e disk_dev_mount_state(const char *path) +{ + int num_mounts; + struct statfs *mntbuf; + disk_mount_e last_state; + int i; + + num_mounts = getmntinfo(&mntbuf, MNT_WAIT); + if (num_mounts == 0) { + ERROR("Failed to get the mount information, errno=%d", errno); + return DISK_MOUNTED_RW; + } + + last_state = DISK_NOT_MOUNTED; + for (i = 0; i < num_mounts; i++) { + struct statfs *mnt = &mntbuf[i]; + + if (strncmp(path, mnt->f_mntfromname, strlen(path)) == 0) { + disk_mount_e cur_state = DISK_NOT_MOUNTED; + if (mnt->f_flags == MNT_RDONLY) + cur_state = DISK_MOUNTED_RO; + else + cur_state = DISK_MOUNTED_RW; + + if (cur_state > last_state) + last_state = cur_state; + } + } + + return last_state; +} void mac_read(unsigned char *buf, int len) { struct ifreq ifr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/arch/arch-generic.c new/diskscan-0.19/arch/arch-generic.c --- old/diskscan-0.18/arch/arch-generic.c 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/arch/arch-generic.c 2015-11-15 21:56:05.000000000 +0100 @@ -17,3 +17,22 @@ return 0; } + +int disk_dev_identify(disk_dev_t *dev, char *vendor, char *model, char *fw_rev, char *serial, bool *is_ata, unsigned char *ata_buf, unsigned *ata_buf_len) +{ + (void)dev; + strcpy(vendor, "UNKNOWN"); + strcpy(model, "UNKNOWN"); + strcpy(fw_rev, "UNKN"); + strcpy(serial, "UNKNOWN"); + *is_ata = 0; + *ata_buf_len = 0; + *ata_buf = 0; + return 0; +} + +void mac_read(unsigned char *buf, int len) +{ + (void)len; + *buf = 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/arch/arch-linux.c new/diskscan-0.19/arch/arch-linux.c --- old/diskscan-0.18/arch/arch-linux.c 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/arch/arch-linux.c 2015-11-15 21:56:05.000000000 +0100 @@ -18,6 +18,7 @@ #include <errno.h> #include <net/if.h> #include <netinet/in.h> +#include <mntent.h> static void strtrim(char *s) { @@ -237,6 +238,79 @@ return 0; } +static disk_mount_e mount_point_check(struct mntent *mnt) +{ + char *next = mnt->mnt_opts; + char *opt; + + /* Device is mounted, check it */ + while ((opt = strtok(next, ", \t\r\n")) != NULL) { + next = NULL; // continue scanning for this string + if (strcmp(opt, "rw") == 0) + return DISK_MOUNTED_RW; + } + + return DISK_MOUNTED_RO; +} + +disk_mount_e disk_dev_mount_state(const char *path) +{ + struct stat dev_st_buf; + struct stat st_buf; + FILE *f = NULL; + struct mntent *mnt; + disk_mount_e state = DISK_MOUNTED_RW; // assume the worst + + f = setmntent("/proc/mounts", "r"); + if (f == NULL) { + ERROR("Failed to open /proc/mounts to know the state, errno=%d", errno); + goto Exit; + } + + if (stat(path, &dev_st_buf) != 0) { + ERROR("Failed to stat the path %s, errno=%d", path, errno); + goto Exit; + } + + if (!S_ISBLK(dev_st_buf.st_mode)) { + ERROR("Device %s is not a block device", path); + goto Exit; // We only want block devices + } + + // From here we assume the disk is not mounted + state = DISK_NOT_MOUNTED; + + while ((mnt = getmntent(f)) != NULL) { + disk_mount_e cur_state = DISK_NOT_MOUNTED; + + /* Ignore non-full-path entries */ + if (mnt->mnt_fsname[0] != '/') + continue; + /* Check for a name prefix match, we may check a full block device and a partition is mounted */ + if (strncmp(path, mnt->mnt_fsname, strlen(path)) == 0) { + cur_state = mount_point_check(mnt); + if (cur_state > state) + state = cur_state; + continue; + } + /* Check for an underlying device match (name may have changed in between actions) */ + if (stat(mnt->mnt_fsname, &st_buf) == 0) { + if (!S_ISBLK(st_buf.st_mode)) + continue; + if (dev_st_buf.st_rdev == st_buf.st_rdev) { + cur_state = mount_point_check(mnt); + if (cur_state > state) + state = cur_state; + } + } + } + +Exit: + if (f) + endmntent(f); + return state; +} + bool disk_dev_open(disk_dev_t *dev, const char *path) { dev->fd = open(path, O_RDWR|O_DIRECT); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/arch/arch-posix.c new/diskscan-0.19/arch/arch-posix.c --- old/diskscan-0.18/arch/arch-posix.c 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/arch/arch-posix.c 2015-11-15 21:56:05.000000000 +0100 @@ -4,8 +4,10 @@ #include <unistd.h> #include <memory.h> #include <errno.h> +#include <stdbool.h> #include "verbose.h" +#include "arch.h" bool disk_dev_open(disk_dev_t *dev, const char *path) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/cli/cli.c new/diskscan-0.19/cli/cli.c --- old/diskscan-0.18/cli/cli.c 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/cli/cli.c 2015-11-15 21:56:05.000000000 +0100 @@ -47,6 +47,7 @@ unsigned scan_size; char *data_log_name; char *data_log_raw_name; + disk_mount_e allowed_mount; }; static void print_header(void) @@ -67,6 +68,8 @@ printf(" -e, --size <size> - Scan size (default to 64K, must be multiple of 512)\n"); printf(" -o, --output <file> - Output file (json)\n"); printf(" -r, --raw-log <file> - Raw log of all scan results (json)\n"); + printf(" --force-mounted - Allow checking a read-only mounted disk\n"); + printf(" --force-mounted-rw - Allow checking a read-write mounted disk\n"); printf("\n"); return 1; } @@ -203,6 +206,7 @@ { int c; int unknown = 0; + static int allowed_mount = DISK_NOT_MOUNTED; opts->scan_size = 64*1024; @@ -215,6 +219,8 @@ {"size", required_argument, 0, 'e'}, {"raw-log", required_argument, 0, 'r'}, {"output", required_argument, 0, 'o'}, + {"force-mounted", no_argument, &allowed_mount, DISK_MOUNTED_RO}, + {"force-mounted-rw", no_argument, &allowed_mount, DISK_MOUNTED_RW}, {0, 0, 0, 0} }; @@ -276,6 +282,7 @@ } opts->disk_path = argv[optind]; + opts->allowed_mount = allowed_mount; return 0; } @@ -306,8 +313,10 @@ { int ret; options_t opts; + memset(&opts, 0, sizeof(opts)); opts.mode = SCAN_MODE_SEQ; + opts.allowed_mount = DISK_NOT_MOUNTED; if (parse_args(argc, argv, &opts)) return 1; @@ -317,7 +326,7 @@ setup_signals(); - if (disk_open(&disk, opts.disk_path, opts.fix, 70)) + if (disk_open(&disk, opts.disk_path, opts.fix, 70, opts.allowed_mount)) return 1; /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/distclean.sh new/diskscan-0.19/distclean.sh --- old/diskscan-0.18/distclean.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/diskscan-0.19/distclean.sh 2015-11-15 21:56:05.000000000 +0100 @@ -0,0 +1,46 @@ +#!/bin/sh + +# distclean.sh for diskscan +# Copyright 2015 Joao Eriberto Mota Filho <eribe...@eriberto.pro.br> +# v2015111402 +# This file can used under GPL-3+ license or BSD-3-Clause. + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +PREFIX="." + +# Files and directories to remove + +OBJS=" CMakeFiles/ \ + Makefile \ + CMakeCache.txt \ + Documentation/diskscan.1 \ + cmake_install.cmake \ + install_manifest.txt \ + libscsicmd/src/CMakeFiles/ \ + libscsicmd/src/Makefile \ + libscsicmd/src/cmake_install.cmake \ + tags" + +# Main procedures + +remove_files () { + if [ -e "$PREFIX/$TARGET" ]; then + echo "Removing $PREFIX/$TARGET" + rm -rf "${PREFIX:?}/$TARGET" + else + echo "$PREFIX/$TARGET NOT FOUND." + fi +} + +# Distclean + +echo "DOING DISTCLEAN..." + +for TARGET in $OBJS +do + remove_files +done + +echo "DONE." +echo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/include/arch.h new/diskscan-0.19/include/arch.h --- old/diskscan-0.18/include/arch.h 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/include/arch.h 2015-11-15 21:56:05.000000000 +0100 @@ -29,6 +29,14 @@ unsigned sense_len; } io_result_t; +typedef enum { + DISK_NOT_MOUNTED = 0, + DISK_MOUNTED_RO = 1, + DISK_MOUNTED_RW = 2, +} disk_mount_e; + +disk_mount_e disk_dev_mount_state(const char *path); + bool disk_dev_open(disk_dev_t *dev, const char *path); void disk_dev_close(disk_dev_t *dev); void disk_dev_cdb_out(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/include/diskscan.h new/diskscan-0.19/include/diskscan.h --- old/diskscan-0.18/include/diskscan.h 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/include/diskscan.h 2015-11-15 21:56:05.000000000 +0100 @@ -87,7 +87,7 @@ data_log_t data_log; } disk_t; -int disk_open(disk_t *disk, const char *path, int fix, unsigned latency_graph_len); +int disk_open(disk_t *disk, const char *path, int fix, unsigned latency_graph_len, disk_mount_e allowed_mount); int disk_scan(disk_t *disk, enum scan_mode mode, unsigned data_size); int disk_close(disk_t *disk); void disk_scan_stop(disk_t *disk); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskscan-0.18/lib/diskscan.c new/diskscan-0.19/lib/diskscan.c --- old/diskscan-0.18/lib/diskscan.c 2015-11-06 20:07:24.000000000 +0100 +++ new/diskscan-0.19/lib/diskscan.c 2015-11-15 21:56:05.000000000 +0100 @@ -269,7 +269,33 @@ (void)disk; } -int disk_open(disk_t *disk, const char *path, int fix, unsigned latency_graph_len) +static const char *disk_mount_str(disk_mount_e mount) +{ + switch (mount) { + case DISK_NOT_MOUNTED: return "not mounted"; + case DISK_MOUNTED_RO: return "mounted read-only"; + case DISK_MOUNTED_RW: return "mounted read-write"; + default: return "unknown"; + } +} + +static int disk_mount_allowed(const char *path, disk_mount_e allowed_mount) +{ + const disk_mount_e mount_state = disk_dev_mount_state(path); + + if (mount_state > allowed_mount) { + ERROR("Disk is currently %s and we only allow %s, use --force-mounted or --force-mounted-rw if the risk of problems is acceptable", disk_mount_str(mount_state), disk_mount_str(allowed_mount)); + return 0; + } + + if (mount_state != DISK_NOT_MOUNTED) { + INFO("Disk is %s but this is allowed with a force option", disk_mount_str(mount_state)); + } + + return 1; +} + +int disk_open(disk_t *disk, const char *path, int fix, unsigned latency_graph_len, disk_mount_e allowed_mount) { memset(disk, 0, sizeof(*disk)); disk->fix = fix; @@ -286,6 +312,11 @@ return 1; } + if (fix && !disk_mount_allowed(path, allowed_mount)) { + ERROR("Better not fix with the disk mounted, mounted fs may get confused when data is possibly modified under its feet"); + return 1; + } + if (!disk_dev_open(&disk->dev, path)) { ERROR("Failed to open path %s, errno=%d: %s", path, errno, strerror(errno)); return 1;