r6597: Make use of libblkid (part of e2fsprogs) for reporting volume GUID, if possible.
authorAlexander Bokovoy <ab@samba.org>
Tue, 3 May 2005 09:57:34 +0000 (09:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:16:29 +0000 (13:16 -0500)
Implement smbclient's 'fsinfo' comand family which allows you to query file
system information in all known levels.
(This used to be commit 660d6e3915d0539dd78c77df6707ea84edb4d509)

source4/client/client.c
source4/ntvfs/posix/config.m4
source4/ntvfs/posix/pvfs_fsinfo.c

index 248113a564c90956b3e6fd1e0c653ce0c6cf177d..a81bacf895851b9cd2551a170ce84460142c335f 100644 (file)
@@ -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}},
index 0fcc948a5b90fad3f853c0aeffe2ec81d2329dc7..7625f8ee813355b62a7d81d7f026e3d904ce6d93 100644 (file)
@@ -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
index 6d92713ac7245a12355238b92c7ad21f71cba834..6046ecb6f8060b65ecea7929dd2f91651201d6a4 100644 (file)
 
 #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;