summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bokovoy <ab@samba.org>2005-05-03 09:57:34 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:16:29 -0500
commit1199f5f561c44fb3075742b6795ac9f64d079742 (patch)
tree5f6f8cb8ca9d46e638d795451fa34c45f02c363e
parent17f1cf095022a88541c461f2ea66940daabcd9a8 (diff)
downloadsamba-1199f5f561c44fb3075742b6795ac9f64d079742.tar.gz
samba-1199f5f561c44fb3075742b6795ac9f64d079742.tar.bz2
samba-1199f5f561c44fb3075742b6795ac9f64d079742.zip
r6597: Make use of libblkid (part of e2fsprogs) for reporting volume GUID, if possible.
Implement smbclient's 'fsinfo' comand family which allows you to query file system information in all known levels. (This used to be commit 660d6e3915d0539dd78c77df6707ea84edb4d509)
-rw-r--r--source4/client/client.c163
-rw-r--r--source4/ntvfs/posix/config.m47
-rw-r--r--source4/ntvfs/posix/pvfs_fsinfo.c28
3 files changed, 196 insertions, 2 deletions
diff --git a/source4/client/client.c b/source4/client/client.c
index 248113a564..a81bacf895 100644
--- a/source4/client/client.c
+++ b/source4/client/client.c
@@ -1673,6 +1673,168 @@ static int cmd_deltree(const char **cmd_ptr)
return 0;
}
+typedef struct {
+ const char *level_name;
+ enum smb_fsinfo_level level;
+} fsinfo_level_t;
+
+fsinfo_level_t fsinfo_levels[] = {
+ {"generic", RAW_QFS_GENERIC},
+ {"dskattr", RAW_QFS_DSKATTR},
+ {"allocation", RAW_QFS_ALLOCATION},
+ {"volume", RAW_QFS_VOLUME},
+ {"volumeinfo", RAW_QFS_VOLUME_INFO},
+ {"sizeinfo", RAW_QFS_SIZE_INFO},
+ {"deviceinfo", RAW_QFS_DEVICE_INFO},
+ {"attributeinfo", RAW_QFS_ATTRIBUTE_INFO},
+ {"unixinfo", RAW_QFS_UNIX_INFO},
+ {"volume-information", RAW_QFS_VOLUME_INFORMATION},
+ {"size-information", RAW_QFS_SIZE_INFORMATION},
+ {"device-information", RAW_QFS_DEVICE_INFORMATION},
+ {"attribute-information", RAW_QFS_ATTRIBUTE_INFORMATION},
+ {"quota-information", RAW_QFS_QUOTA_INFORMATION},
+ {"fullsize-information", RAW_QFS_FULL_SIZE_INFORMATION},
+ {"objectid", RAW_QFS_OBJECTID_INFORMATION},
+ {NULL, RAW_QFS_GENERIC}
+};
+
+
+static int cmd_fsinfo(const char **cmd_ptr)
+{
+ pstring level_name;
+ fstring buf;
+ int ret = 0;
+ union smb_fsinfo fsinfo;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ fsinfo_level_t *fsinfo_level;
+
+ if (!next_token(cmd_ptr,buf,NULL,sizeof(buf))) {
+ d_printf("fsinfo <level>, where level is one of following:\n");
+ fsinfo_level = fsinfo_levels;
+ while(fsinfo_level->level_name) {
+ d_printf("%s\n", fsinfo_level->level_name);
+ fsinfo_level++;
+ }
+ return 1;
+ }
+
+ fsinfo_level = fsinfo_levels;
+ while(fsinfo_level->level_name && !strequal(buf,fsinfo_level->level_name)) {
+ fsinfo_level++;
+ }
+
+ if (!fsinfo_level->level_name) {
+ d_printf("wrong level name!\n");
+ return 1;
+ }
+
+ mem_ctx = talloc_init("fsinfo-level-%s", fsinfo_level->level_name);
+ fsinfo.generic.level = fsinfo_level->level;
+ status = smb_raw_fsinfo(cli->tree, mem_ctx, &fsinfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("fsinfo-level-%s - %s\n", fsinfo_level->level_name, nt_errstr(status));
+ ret = 1;
+ goto done;
+ }
+
+ d_printf("fsinfo-level-%s:\n", fsinfo_level->level_name);
+ switch(fsinfo.generic.level) {
+ case RAW_QFS_GENERIC:
+ d_printf("\tblock_size: %lu\n", fsinfo.generic.out.block_size);
+ d_printf("\tblocks_total: %llu\n", fsinfo.generic.out.blocks_total);
+ d_printf("\tblocks_free: %llu\n", fsinfo.generic.out.blocks_free);
+ d_printf("\tfs_id: %lu\n", fsinfo.generic.out.fs_id);
+ d_printf("\tcreate_time: %s\n", nt_time_string(mem_ctx,fsinfo.generic.out.create_time));
+ d_printf("\tserial_number: %lu\n", fsinfo.generic.out.serial_number);
+ d_printf("\tfs_attr: %lx\n", fsinfo.generic.out.fs_attr);
+ d_printf("\tmax_file_component_length: %lu\n", fsinfo.generic.out.max_file_component_length);
+ d_printf("\tdevice_type: %lu\n", fsinfo.generic.out.device_type);
+ d_printf("\tdevice_characteristics: %lx\n", fsinfo.generic.out.device_characteristics);
+ d_printf("\tquota_soft: %llu\n", fsinfo.generic.out.quota_soft);
+ d_printf("\tquota_hard: %llu\n", fsinfo.generic.out.quota_hard);
+ d_printf("\tquota_flags: %llx\n", fsinfo.generic.out.quota_flags);
+ d_printf("\tGUID: %s\n", GUID_string(mem_ctx,&fsinfo.generic.out.guid));
+ d_printf("\tvolume_name: %s\n", fsinfo.generic.out.volume_name);
+ d_printf("\tfs_type: %s\n", fsinfo.generic.out.fs_type);
+ break;
+ case RAW_QFS_DSKATTR:
+ d_printf("\tunits_total: %hu\n", fsinfo.dskattr.out.units_total);
+ d_printf("\tblocks_per_unit: %hu\n", fsinfo.dskattr.out.blocks_per_unit);
+ d_printf("\tblocks_size: %hu\n", fsinfo.dskattr.out.block_size);
+ d_printf("\tunits_free: %hu\n", fsinfo.dskattr.out.units_free);
+ break;
+ case RAW_QFS_ALLOCATION:
+ d_printf("\tfs_id: %lu\n", fsinfo.allocation.out.fs_id);
+ d_printf("\tsectors_per_unit: %lu\n", fsinfo.allocation.out.sectors_per_unit);
+ d_printf("\ttotal_alloc_units: %lu\n", fsinfo.allocation.out.total_alloc_units);
+ d_printf("\tavail_alloc_units: %lu\n", fsinfo.allocation.out.avail_alloc_units);
+ d_printf("\tbytes_per_sector: %hu\n", fsinfo.allocation.out.bytes_per_sector);
+ break;
+ case RAW_QFS_VOLUME:
+ d_printf("\tserial_number: %lu\n", fsinfo.volume.out.serial_number);
+ d_printf("\tvolume_name: %s\n", fsinfo.volume.out.volume_name.s);
+ break;
+ case RAW_QFS_VOLUME_INFO:
+ case RAW_QFS_VOLUME_INFORMATION:
+ d_printf("\tcreate_time: %s\n", nt_time_string(mem_ctx,fsinfo.volume_info.out.create_time));
+ d_printf("\tserial_number: %lu\n", fsinfo.volume_info.out.serial_number);
+ d_printf("\tvolume_name: %s\n", fsinfo.volume_info.out.volume_name.s);
+ break;
+ case RAW_QFS_SIZE_INFO:
+ case RAW_QFS_SIZE_INFORMATION:
+ d_printf("\ttotal_alloc_units: %llu\n", fsinfo.size_info.out.total_alloc_units);
+ d_printf("\tavail_alloc_units: %llu\n", fsinfo.size_info.out.avail_alloc_units);
+ d_printf("\tsectors_per_unit: %lu\n", fsinfo.size_info.out.sectors_per_unit);
+ d_printf("\tbytes_per_sector: %lu\n", fsinfo.size_info.out.bytes_per_sector);
+ break;
+ case RAW_QFS_DEVICE_INFO:
+ case RAW_QFS_DEVICE_INFORMATION:
+ d_printf("\tdevice_type: %lu\n", fsinfo.device_info.out.device_type);
+ d_printf("\tcharacteristics: %lx\n", fsinfo.device_info.out.characteristics);
+ break;
+ case RAW_QFS_ATTRIBUTE_INFORMATION:
+ case RAW_QFS_ATTRIBUTE_INFO:
+ d_printf("\tfs_attr: %lx\n", fsinfo.attribute_info.out.fs_attr);
+ d_printf("\tmax_file_component_length: %lu\n", fsinfo.attribute_info.out.max_file_component_length);
+ d_printf("\tfs_type: %s\n", fsinfo.attribute_info.out.fs_type.s);
+ break;
+ case RAW_QFS_UNIX_INFO:
+ d_printf("\tmajor_version: %hu\n", fsinfo.unix_info.out.major_version);
+ d_printf("\tminor_version: %hu\n", fsinfo.unix_info.out.minor_version);
+ d_printf("\tcapability: %llx\n", fsinfo.unix_info.out.capability);
+ break;
+ case RAW_QFS_QUOTA_INFORMATION:
+ d_printf("\tunknown[3]: [%llu,%llu,%llu]\n", fsinfo.quota_information.out.unknown[0],
+ fsinfo.quota_information.out.unknown[1],
+ fsinfo.quota_information.out.unknown[2]);
+ d_printf("\tquota_soft: %llu\n", fsinfo.quota_information.out.quota_soft);
+ d_printf("\tquota_hard: %llu\n", fsinfo.quota_information.out.quota_hard);
+ d_printf("\tquota_flags: %llx\n", fsinfo.quota_information.out.quota_flags);
+ break;
+ case RAW_QFS_FULL_SIZE_INFORMATION:
+ d_printf("\ttotal_alloc_units: %llu\n", fsinfo.full_size_information.out.total_alloc_units);
+ d_printf("\tcall_avail_alloc_units: %llu\n", fsinfo.full_size_information.out.call_avail_alloc_units);
+ d_printf("\tactual_avail_alloc_units: %llu\n", fsinfo.full_size_information.out.actual_avail_alloc_units);
+ d_printf("\tsectors_per_unit: %lu\n", fsinfo.full_size_information.out.sectors_per_unit);
+ d_printf("\tbytes_per_sector: %lu\n", fsinfo.full_size_information.out.bytes_per_sector);
+ break;
+ case RAW_QFS_OBJECTID_INFORMATION:
+ d_printf("\tGUID: %s\n", GUID_string(mem_ctx,&fsinfo.objectid_information.out.guid));
+ d_printf("\tunknown[6]: [%llu,%llu,%llu,%llu,%llu,%llu]\n",
+ fsinfo.objectid_information.out.unknown[0],
+ fsinfo.objectid_information.out.unknown[2],
+ fsinfo.objectid_information.out.unknown[3],
+ fsinfo.objectid_information.out.unknown[4],
+ fsinfo.objectid_information.out.unknown[5],
+ fsinfo.objectid_information.out.unknown[6] );
+ break;
+ }
+
+ done:
+ talloc_free(mem_ctx);
+ return ret;
+}
/****************************************************************************
show as much information as possible about a file
@@ -2641,6 +2803,7 @@ static struct
{"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"eainfo",cmd_eainfo,"<file> show EA contents for a file",{COMPL_NONE,COMPL_NONE}},
{"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
+ {"fsinfo",cmd_fsinfo,"query file system info",{COMPL_NONE,COMPL_NONE}},
{"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
{"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4
index 0fcc948a5b..7625f8ee81 100644
--- a/source4/ntvfs/posix/config.m4
+++ b/source4/ntvfs/posix/config.m4
@@ -31,3 +31,10 @@ AC_CHECK_FUNCS(flistxattr)
if test x"$ac_cv_func_flistxattr" = x"yes"; then
AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support])
fi
+
+AC_CHECK_HEADERS(blkid/blkid.h)
+AC_SEARCH_LIBS(blkid_get_cache, [blkid])
+AC_CHECK_FUNCS(blkid_get_cache)
+if test x"$ac_cv_func_blkid_get_cache" = x"yes"; then
+ AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)])
+fi
diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c
index 6d92713ac7..6046ecb6f8 100644
--- a/source4/ntvfs/posix/pvfs_fsinfo.c
+++ b/source4/ntvfs/posix/pvfs_fsinfo.c
@@ -22,7 +22,12 @@
#include "includes.h"
#include "vfs_posix.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+/* We use libblkid out of e2fsprogs to identify UUID of a volume */
+#ifdef HAVE_LIBBLKID
+#include <blkid/blkid.h>
+#endif
/*
return filesystem space info
@@ -136,8 +141,27 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs,
return NT_STATUS_OK;
case RAW_QFS_OBJECTID_INFORMATION:
- ZERO_STRUCT(fs->objectid_information.out);
- return NT_STATUS_OK;
+ {
+#ifdef HAVE_LIBBLKID
+ NTSTATUS status;
+ blkid_cache blk_cache = NULL;
+ const char *uuid_value;
+ const char *blkid_devname;
+
+#endif
+ ZERO_STRUCT(fs->objectid_information.out);
+#ifdef HAVE_LIBBLKID
+ blkid_devname = blkid_devno_to_devname(st.st_dev);
+ if (!blk_cache && blkid_get_cache(&blk_cache,NULL) < 0 ) {
+ return NT_STATUS_DEVICE_CONFIGURATION_ERROR;
+ }
+ if ((uuid_value = blkid_get_tag_value(blk_cache, "UUID", blkid_devname))) {
+ GUID_from_string(uuid_value, &fs->objectid_information.out.guid);
+ free(uuid_value);
+ }
+#endif
+ return NT_STATUS_OK;
+ }
}
return NT_STATUS_INVALID_LEVEL;