From 2d294045c7adc88edb517fa84e2126bfd45fcbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 22 Apr 2009 14:45:29 +0000 Subject: [PATCH] Add an extra option to isvolume to check if the underlaying partition is perhaps read-only, while the volume appears to be writable because of the filesystem overlays. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30327 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/bin/Jamfile | 2 +- src/bin/isvolume.cpp | 98 +++++++++++++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 30 deletions(-) diff --git a/src/bin/Jamfile b/src/bin/Jamfile index ae20c0e409..dc9eb4d4d8 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -32,7 +32,6 @@ StdBinCommands finddir.c hd.c idestatus.c - isvolume.cpp listarea.c listimage.c listport.c @@ -110,6 +109,7 @@ StdBinCommands # Haiku-specific apps which need libbe.so if $(TARGET_PLATFORM) = haiku { StdBinCommands + isvolume.cpp shutdown.cpp : be : $(haiku-utils_rsrc) ; } diff --git a/src/bin/isvolume.cpp b/src/bin/isvolume.cpp index f8b2ef014d..509020982d 100644 --- a/src/bin/isvolume.cpp +++ b/src/bin/isvolume.cpp @@ -1,17 +1,21 @@ /* - * Copyright 2002-2006, Haiku Inc. All rights reserved. + * Copyright 2002-2009, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Jonas Sundstrom, jonas.sundstrom@kirilla.com + * Stephan Aßmus */ - #include #include #include +#include +#include +#include + static void usage() @@ -19,17 +23,19 @@ usage() fprintf(stderr, "Usage: isvolume {-OPTION} [volumename]\n" " Where OPTION is one of:\n" - " -readonly - volume is read-only\n" - " -query - volume supports queries\n" - " -attribute - volume supports attributes\n" - " -mime - volume supports MIME information\n" - " -shared - volume is shared\n" - " -persistent - volume is backed on permanent storage\n" - " -removable - volume is on removable media\n" + " -readonly - volume is read-only\n" + " -readonly-partion - partition for the volume is read-only\n" + " -query - volume supports queries\n" + " -attribute - volume supports attributes\n" + " -mime - volume supports MIME information\n" + " -shared - volume is shared\n" + " -persistent - volume is backed on permanent storage\n" + " -removable - volume is on removable media\n" " If the option is true for the named volume, 'yes' is printed\n" " and if the option is false, 'no' is printed. Multiple options\n" " can be specified in which case all of them must be true.\n\n" - " If no volume is specified, the volume of the current directory is assumed.\n"); + " If no volume is specified, the volume of the current directory is " + "assumed.\n"); } @@ -39,7 +45,8 @@ main(int argc, char** argv) dev_t volumeDevice = dev_for_path("."); uint32 isVolumeFlags = 0; fs_info volumeInfo; - + bool doPartitionReadOnlyCheck = false; + for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--help")) { usage(); @@ -47,35 +54,67 @@ main(int argc, char** argv) } if (argv[i][0] == '-') { - if (! strcmp(argv[i], "-readonly")) - isVolumeFlags |= B_FS_IS_READONLY; - else if (! strcmp(argv[i], "-query")) - isVolumeFlags |= B_FS_HAS_QUERY; - else if (! strcmp(argv[i], "-attribute")) - isVolumeFlags |= B_FS_HAS_ATTR; - else if (! strcmp(argv[i], "-mime")) - isVolumeFlags |= B_FS_HAS_MIME; - else if (! strcmp(argv[i], "-shared")) - isVolumeFlags |= B_FS_IS_SHARED; - else if (! strcmp(argv[i], "-persistent")) - isVolumeFlags |= B_FS_IS_PERSISTENT; - else if (! strcmp(argv[i], "-removable")) - isVolumeFlags |= B_FS_IS_REMOVABLE; + if (strcmp(argv[i], "-readonly") == 0) + isVolumeFlags |= B_FS_IS_READONLY; + else if (strcmp(argv[i], "-query") == 0) + isVolumeFlags |= B_FS_HAS_QUERY; + else if (strcmp(argv[i], "-attribute") == 0) + isVolumeFlags |= B_FS_HAS_ATTR; + else if (strcmp(argv[i], "-mime") == 0) + isVolumeFlags |= B_FS_HAS_MIME; + else if (strcmp(argv[i], "-shared") == 0) + isVolumeFlags |= B_FS_IS_SHARED; + else if (strcmp(argv[i], "-persistent") == 0) + isVolumeFlags |= B_FS_IS_PERSISTENT; + else if (strcmp(argv[i], "-removable") == 0) + isVolumeFlags |= B_FS_IS_REMOVABLE; + else if (strcmp(argv[i], "-readonly-partion")) + doPartitionReadOnlyCheck = true; else { fprintf(stderr, - "%s: option %s is not understood (use --help for help)\n", argv[0], argv[i]); + "%s: option %s is not understood (use --help for help)\n", + argv[0], argv[i]); return 1; } } else { volumeDevice = dev_for_path(argv[i]); - + if (volumeDevice < 0) { - fprintf(stderr, "%s: can't get information about volume: %s\n", argv[0], argv[i]); + fprintf(stderr, "%s: can't get information about volume: %s\n", + argv[0], argv[i]); return 1; } } } + if (doPartitionReadOnlyCheck) { + // This requires an extra code-path, because volumes may now appear + // writable, but only because of the "write" file-system overlay. + BVolume volume(volumeDevice); + status_t ret = volume.InitCheck(); + if (ret != B_OK) { + fprintf(stderr, "%s: failed to get BVolume for device %ld: %s\n", + argv[0], volumeDevice, strerror(ret)); + return 1; + } + + BDiskDeviceRoster roster; + BDiskDevice diskDevice; + BPartition* partition; + ret = roster.FindPartitionByVolume(volume, &diskDevice, + &partition); + if (ret != B_OK) { + fprintf(stderr, "%s: failed to get partition for device %ld: %s\n", + argv[0], volumeDevice, strerror(ret)); + return 1; + } + // check this option directly and not via fs_stat_dev() + if (partition->IsReadOnly()) { + printf("yes\n"); + return 0; + } + } + if (fs_stat_dev(volumeDevice, &volumeInfo) == B_OK) { if (volumeInfo.flags & isVolumeFlags) printf("yes\n"); @@ -84,7 +123,8 @@ main(int argc, char** argv) return 0; } else { - fprintf(stderr, "%s: can't get information about dev_t: %ld\n", argv[0], volumeDevice); + fprintf(stderr, "%s: can't get information about dev_t: %ld\n", + argv[0], volumeDevice); return 1; } }