From 10d49b6e200bb4234a2611e2882e646bf811cd68 Mon Sep 17 00:00:00 2001 From: johann Date: Fri, 7 Mar 2008 07:50:05 +0000 Subject: [PATCH] Branch HEAD b=13805 i=ericm i=bobijam add support for several checksum algorithms. Currently, CRC32 and Adler-32 are supported. The checksum type can be changed on the fly through /proc/fs/lustre/osc/*/checksum_type. --- lustre/ChangeLog | 91 ++++++++++++++++++++------------------ lustre/include/linux/obd_support.h | 64 +++++++++++++++++++++++++++ lustre/include/lustre/lustre_idl.h | 24 ++++++++-- lustre/include/obd.h | 30 +++++++++++-- lustre/include/obd_support.h | 2 + lustre/ldlm/ldlm_lib.c | 7 +++ lustre/liblustre/Makefile.am | 2 +- lustre/liblustre/genlib.sh | 1 + lustre/llite/llite_lib.c | 14 ++++++ lustre/obdfilter/filter.c | 24 ++++++++++ lustre/osc/lproc_osc.c | 57 ++++++++++++++++++++++++ lustre/osc/osc_request.c | 90 ++++++++++++++++++++++++------------- lustre/ost/ost_handler.c | 36 ++++++++++----- lustre/ptlrpc/import.c | 32 ++++++++++++++ lustre/ptlrpc/pack_generic.c | 2 +- lustre/ptlrpc/wiretest.c | 19 +++++--- lustre/tests/sanity.sh | 69 ++++++++++++++++++++++++----- lustre/tests/test-framework.sh | 6 +++ lustre/utils/wirecheck.c | 7 ++- lustre/utils/wiretest.c | 21 +++++---- 20 files changed, 480 insertions(+), 118 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index d6921a5..27cfdd9 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -22,10 +22,10 @@ Frequency : occasional Bugzilla : 13537 Description: Correctly check stale fid, not start epoch if ost not support SOM Details : open with flag O_CREATE need set old fid in op_fid3 because op_fid2 - overwrited with new generated fid, but mds can anwer with one of these - two fids and both is not stale. setattr incorectly start epoch and - assume will be called done_writeting, but without SOM done_writing - never called. + overwrited with new generated fid, but mds can anwer with one of these + two fids and both is not stale. setattr incorectly start epoch and + assume will be called done_writeting, but without SOM done_writing + never called. Severity : major Frequency : rare, depends on device drivers and load @@ -41,9 +41,9 @@ Severity : normal Frequency : occasional Bugzilla : 13730 Description: Do not fail import if osc_interpret_create gets -EAGAIN -Details : If osc_interpret_create got -EAGAIN it immediately exits and - wakeup oscc_waitq. After wakeup oscc_wait_for_objects call - oscc_has_objects and see OSC has no objests and call +Details : If osc_interpret_create got -EAGAIN it immediately exits and + wakeup oscc_waitq. After wakeup oscc_wait_for_objects call + oscc_has_objects and see OSC has no objests and call oscc_internal_create to resend create request. Severity : enhancement @@ -84,7 +84,7 @@ Details : Don't allow skipping OSTs if index has been specified, make locking Severity : normal Bugzilla : 12228 Description: LBUG in ptlrpc_check_set() bad phase ebc0de00 -Details : access to bitfield in structure is always rounded to long +Details : access to bitfield in structure is always rounded to long and this produce problem with not atomic change any bit. Severity : normal @@ -100,7 +100,7 @@ Description: If llog cancel was not send before clean_exports phase, this can produce deadlock in llog code. Details : If llog thread has last reference to obd and call class_import_put this produce deadlock because llog_cleanup_commit_master wait when - last llog_commit_thread exited, but this never success because was + last llog_commit_thread exited, but this never success because was called from llog_commit_thread. Severity : normal @@ -160,7 +160,7 @@ Frequency : rare, at shutdown Description: access already free / zero obd_namespace. Details : if client_disconnect_export was called without force flag set, and exist connect request in flight, this can produce access to - NULL pointer (or already free pointer) when connect_interpret + NULL pointer (or already free pointer) when connect_interpret store ocd flags in obd_namespace. Severity : minor @@ -178,7 +178,7 @@ Details : Make lustre randomly failed allocating memory for testing purpose. Severity : enhancement Bugzilla : 12702 Description: lost problems with lov objid file -Details : Fixes some scability and access to not inited memory problems +Details : Fixes some scability and access to not inited memory problems in work with lov objdid file. Severity : major @@ -220,18 +220,18 @@ Description: Update to RHEL4 latest kernel. Severity : enhancement Bugzilla : 13690 Description: Build SLES10 patchless client fails -Details : The configure was broken by run ./configure with +Details : The configure was broken by run ./configure with --with-linux-obj=.... argument for patchless client. When the configure use --with-linux-obj, the LINUXINCLUDE= -Iinclude - can't search header adequately. Use absolute path such as - -I($LINUX)/include instead. + can't search header adequately. Use absolute path such as + -I($LINUX)/include instead. Severity : normal Bugzilla : 13888 Description: interrupt oig_wait produce painc on resend. Details : brw_redo_request can be used for resend requests from ptlrpcd and private set, and this produce situation when rq_ptlrpcd_data not - copyed to new allocated request and triggered LBUG on assert + copyed to new allocated request and triggered LBUG on assert req->rq_ptlrpcd_data != NULL. But this member used only for wakeup ptlrpcd set if request is changed and can be safety changed to use rq_set directly. @@ -256,10 +256,10 @@ Details : This causes SLES 10 clients to behave as patchless clients Severity : enhancement Bugzilla : 2262 Description: self-adjustable client's lru lists -Details : use adaptive algorithm for managing client cached locks lru +Details : use adaptive algorithm for managing client cached locks lru lists according to current server load, other client's work - pattern, memory activities, etc. Both, server and client - side namespaces provide number of proc tunables for controlling + pattern, memory activities, etc. Both, server and client + side namespaces provide number of proc tunables for controlling things Severity : enhancement @@ -381,7 +381,7 @@ Details : set obd_health_check_timeout as 1.5x of obd_timeout Severity : normal Bugzilla : 12192 Description: llapi_file_create() does not allow some changes -Details : add llapi_file_open() that allows specifying the mode and +Details : add llapi_file_open() that allows specifying the mode and open flags, and also returns an open file handle. Severity : normal @@ -392,9 +392,9 @@ Details : Remove mnt_lustre_list in vfs_intent-2.6-rhel4.patch. Severity : normal Bugzilla : 10657 Description: Add journal checksum support.(Kernel part) -Details : The journal checksum feature adds two new flags i.e - JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT and - JBD2_FEATURE_COMPAT_CHECKSUM. JBD2_FEATURE_CHECKSUM flag +Details : The journal checksum feature adds two new flags i.e + JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT and + JBD2_FEATURE_COMPAT_CHECKSUM. JBD2_FEATURE_CHECKSUM flag indicates that the commit block contains the checksum for the blocks described by the descriptor blocks. Now commit record can be sent to disk without waiting for descriptor @@ -414,7 +414,7 @@ Details : execute lfs setstripe on client Severity : major Bugzilla : 12223 Description: mds_obd_create error creating tmp object -Details : When the user sets quota on root, llog will be affected and can't +Details : When the user sets quota on root, llog will be affected and can't create files and write files. Severity : normal @@ -422,7 +422,7 @@ Frequency : Always on ia64 patchless client, and possibly others. Bugzilla : 12826 Description: Add EXPORT_SYMBOL check for node_to_cpumask symbol. Details : This allows the patchless client to be loaded on architectures - without this export. + without this export. Severity : normal Bugzilla : 13039 @@ -500,7 +500,7 @@ Details : When generating the bio request for lustre file writes the Severity : normal Bugzilla : 11230 -Description: Tune the kernel for good SCSI performance. +Description: Tune the kernel for good SCSI performance. Details : Set the value of /sys/block/{dev}/queue/max_sectors_kb to the value of /sys/block/{dev}/queue/max_hw_sectors_kb in mount_lustre. @@ -542,8 +542,8 @@ Frequency : only on ppc Bugzilla : 12234 Description: /proc/fs/lustre/devices broken on ppc Details : The patch as applied to 1.6.2 doesn't look correct for all arches. - We should make sure the type of 'index' is loff_t and then cast - explicitly as needed below. Do not assign an explicitly cast + We should make sure the type of 'index' is loff_t and then cast + explicitly as needed below. Do not assign an explicitly cast loff_t to an int. Severity : normal @@ -562,14 +562,14 @@ Severity : normal Bugzilla : 13304 Frequency : Always, for kernels after 2.6.16 Description: Fix warning idr_remove called for id=.. which is not allocated. -Details : Last kernels save old s_dev before kill super and not allow +Details : Last kernels save old s_dev before kill super and not allow to restore from callback - restore it before call kill_anon_super. Severity : minor Bugzilla : 12948 Description: buffer overruns could theoretically occur Details : llapi_semantic_traverse() modifies the "path" argument by - appending values to the end of the origin string, and a + appending values to the end of the origin string, and a overrun may occur. Adding buffer overrun check in liblustreapi. Severity : normal @@ -602,12 +602,12 @@ Severity : critical Bugzilla : 13751 Description: Kernel patches update for RHEL5 2.6.18-8.1.14.el5. Details : Modify target file & which_patch. - A flaw was found in the IA32 system call emulation provided - on AMD64 and Intel 64 platforms. An improperly validated 64-bit - value could be stored in the %RAX register, which could trigger an - out-of-bounds system call table access. An untrusted local user - could exploit this flaw to run code in the kernel - (ie a root privilege escalation). (CVE-2007-4573). + A flaw was found in the IA32 system call emulation provided + on AMD64 and Intel 64 platforms. An improperly validated 64-bit + value could be stored in the %RAX register, which could trigger an + out-of-bounds system call table access. An untrusted local user + could exploit this flaw to run code in the kernel + (ie a root privilege escalation). (CVE-2007-4573). Severity : major Bugzilla : 13093 @@ -621,7 +621,7 @@ Bugzilla : 13454 Description: Add jbd statistics patch for RHEL5 and 2.6.18-vanilla Severity : minor -Bugzilla : 13732 +Bugzilla : 13732 Description: change order of libsysio includes Details : '#include sysio.h' should always come before '#include xtio.h' @@ -759,13 +759,13 @@ Severity : enhancement Bugzilla : 14729 Description: SNMP support enhancement Details : Adding total number of sampled request for an MDS node in snmp - support. + support. Severity : enhancement Bugzilla : 14748 Description: Optimize ldlm waiting list processing for PR extent locks Details : When processing waiting list for read extent lock and meeting read - lock that is same or wider to it that is not contended, skip + lock that is same or wider to it that is not contended, skip processing rest of the list and immediatelly return current status of conflictness, since we are guaranteed there are no conflicting locks in the rest of the list. @@ -777,19 +777,26 @@ Details : When the failover node is the primary node, it is possible to have two identical connections in imp_conn_list. We must compare not conn's pointers but NIDs, otherwise we can defeat connection throttling. - + Severity : normal Bugzilla : 13821 Description: port llog fixes from b1_6 into HEAD Details : Port llog reference couting and some llog cleanups from b1_6 - (bug 10800) into HEAD, for protect from panic and access to already + (bug 10800) into HEAD, for protect from panic and access to already free llog structures. Severity : normal Bugzilla : 14483 -Description: Detect stride IO mode in read-ahead +Description: Detect stride IO mode in read-ahead Details : When a client does stride read, read-ahead should detect that and - read-ahead pages according to the detected stride pattern. + read-ahead pages according to the detected stride pattern. + +Severity : normal +Bugzilla : 13805 +Description: data checksumming impacts single node performance +Details : add support for several checksum algorithm. Currently, only CRC32 + and Adler-32 are supported. The checksum type can be changed on + the fly via /proc/fs/lustre/osc/*/checksum_type. -------------------------------------------------------------------------------- diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index d6f57c3..362cbcb 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -37,6 +37,7 @@ #endif #include #include +#include /* Prefer the kernel's version, if it exports it, because it might be * optimized for this CPU. */ @@ -87,6 +88,69 @@ static inline __u32 zlib_adler32(__u32 adler, unsigned char const *p, # endif #endif /* __KERNEL__ */ +static inline __u32 init_checksum(cksum_type_t cksum_type) +{ + switch(cksum_type) { + case OBD_CKSUM_CRC32: + return ~0U; +#ifdef HAVE_ADLER + case OBD_CKSUM_ADLER: + return 1U; +#endif + default: + CERROR("Unknown checksum type (%x)!!!\n", cksum_type); + LBUG(); + } + return 0; +} + +static inline __u32 compute_checksum(__u32 cksum, unsigned char const *p, + size_t len, cksum_type_t cksum_type) +{ + switch(cksum_type) { + case OBD_CKSUM_CRC32: + return crc32_le(cksum, p, len); +#ifdef HAVE_ADLER + case OBD_CKSUM_ADLER: + return zlib_adler32(cksum, p, len); +#endif + default: + CERROR("Unknown checksum type (%x)!!!\n", cksum_type); + LBUG(); + } + return 0; +} + +static inline obd_flag cksum_type_pack(cksum_type_t cksum_type) +{ + switch(cksum_type) { + case OBD_CKSUM_CRC32: + return OBD_FL_CKSUM_CRC32; +#ifdef HAVE_ADLER + case OBD_CKSUM_ADLER: + return OBD_FL_CKSUM_ADLER; +#endif + default: + CWARN("unknown cksum type %x\n", cksum_type); + } + return OBD_FL_CKSUM_CRC32; +} + +static inline cksum_type_t cksum_type_unpack(obd_flag o_flags) +{ + o_flags &= OBD_FL_CKSUM_ALL; + if ((o_flags - 1) & o_flags) + CWARN("several checksum types are set: %x\n", o_flags); + if (o_flags & OBD_FL_CKSUM_ADLER) +#ifdef HAVE_ADLER + return OBD_CKSUM_ADLER; +#else + CWARN("checksum type is set to adler32, but adler32 is not " + "supported (%x)\n", o_flags); +#endif + return OBD_CKSUM_CRC32; +} + #ifdef __KERNEL__ # include # include diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 2a8786f..d79772c 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -578,7 +578,7 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb); OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_INDEX | \ OBD_CONNECT_BRW_SIZE | OBD_CONNECT_QUOTA64 | \ OBD_CONNECT_OSS_CAPA | OBD_CONNECT_CANCELSET | \ - OBD_CONNECT_FID | \ + OBD_CONNECT_FID | OBD_CONNECT_CKSUM | \ LRU_RESIZE_CONNECT_FLAG) #define ECHO_CONNECT_SUPPORTED (0) #define MGS_CONNECT_SUPPORTED (OBD_CONNECT_VERSION | OBD_CONNECT_FID) @@ -607,14 +607,25 @@ struct obd_connect_data { __u32 ocd_nllg; /* non-local-lustre-group */ __u64 ocd_transno; /* first transno from client to be replayed */ __u32 ocd_group; /* MDS group on OST */ - __u32 padding1; /* also fix lustre_swab_connect */ + __u32 ocd_cksum_types; /* supported checksum algorithms */ + __u64 padding1; /* also fix lustre_swab_connect */ __u64 padding2; /* also fix lustre_swab_connect */ - __u64 padding3; /* also fix lustre_swab_connect */ }; extern void lustre_swab_connect(struct obd_connect_data *ocd); /* + * Supported checksum algorithms. Up to 32 checksum types are supported. + * (32-bit mask stored in obd_connect_data::ocd_cksum_types) + * Please update DECLARE_CKSUM_NAME/OBD_CKSUM_ALL in obd.h when adding a new + * algorithm and also the OBD_FL_CKSUM* flags. + */ +typedef enum { + OBD_CKSUM_CRC32 = 0x00000001, + OBD_CKSUM_ADLER = 0x00000002, +} cksum_type_t; + +/* * OST requests: OBDO & OBD request records */ @@ -674,6 +685,13 @@ typedef uint32_t obd_count; #define OBD_FL_TRUNCLOCK (0x00000800) /* + * Checksum types + */ +#define OBD_FL_CKSUM_CRC32 (0x00001000) +#define OBD_FL_CKSUM_ADLER (0x00002000) +#define OBD_FL_CKSUM_ALL (OBD_FL_CKSUM_CRC32 | OBD_FL_CKSUM_ADLER) + +/* * This should not be smaller than sizeof(struct lustre_handle) + sizeof(struct * llog_cookie) + sizeof(struct ll_fid). Nevertheless struct ll_fid is not * longer stored in o_inline, we keep this just for case. diff --git a/lustre/include/obd.h b/lustre/include/obd.h index c9041ee..ce00d17 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -453,9 +453,13 @@ struct client_obd { atomic_t cl_mgc_refcount; struct obd_export *cl_mgc_mgsexp; - /* Flags section */ - unsigned long cl_checksum:1; /* debug checksums */ - + /* checksumming for data sent over the network */ + unsigned int cl_checksum:1; /* 0 = disabled, 1 = enabled */ + /* supported checksum types that are worked out at connect time */ + __u32 cl_supp_cksum_types; + /* checksum algorithm to be used */ + cksum_type_t cl_cksum_type; + /* also protected by the poorly named _loi_list_lock lock above */ struct osc_async_rc cl_ar; @@ -1438,4 +1442,24 @@ static inline struct lustre_capa *oinfo_capa(struct obd_info *oinfo) return oinfo->oi_capa; } +/* + * Checksums + */ + +#ifdef HAVE_ADLER +/* Default preferred checksum algorithm to use (if supported by the server) */ +#define OSC_DEFAULT_CKSUM OBD_CKSUM_ADLER +/* Adler-32 is supported */ +#define CHECKSUM_ADLER OBD_CKSUM_ADLER +#else +#define OSC_DEFAULT_CKSUM OBD_CKSUM_CRC32 +#define CHECKSUM_ADLER 0 +#endif + +#define OBD_CKSUM_ALL (OBD_CKSUM_CRC32 | CHECKSUM_ADLER) + +/* Checksum algorithm names. Must be defined in the same order as the + * OBD_CKSUM_* flags. */ +#define DECLARE_CKSUM_NAME char *cksum_name[] = {"crc32", "adler"} + #endif /* __OBD_H */ diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index ce093b8..5d7a407 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -215,6 +215,8 @@ int __obd_fail_check_set(__u32 id, __u32 value, int set); #define OBD_FAIL_OSC_CHECKSUM_RECEIVE 0x408 #define OBD_FAIL_OSC_CHECKSUM_SEND 0x409 #define OBD_FAIL_OSC_BRW_PREP_REQ2 0x40a +#define OBD_FAIL_OSC_CONNECT_CKSUM 0x40b +#define OBD_FAIL_OSC_CKSUM_ADLER_ONLY 0x40c #define OBD_FAIL_PTLRPC 0x500 #define OBD_FAIL_PTLRPC_ACK 0x501 diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index a5ce738..3b2ab47 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -276,7 +276,14 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) cfs_waitq_init(&cli->cl_destroy_waitq); atomic_set(&cli->cl_destroy_in_flight, 0); #ifdef ENABLE_CHECKSUM + /* Turn on checksumming by default. */ cli->cl_checksum = 1; + /* + * The supported checksum types will be worked out at connect time + * Set cl_chksum* to CRC32 for now to avoid returning screwed info + * through procfs. + */ + cli->cl_cksum_type = cli->cl_supp_cksum_types = OBD_CKSUM_CRC32; #endif atomic_set(&cli->cl_resends, OSC_DEFAULT_RESENDS); diff --git a/lustre/liblustre/Makefile.am b/lustre/liblustre/Makefile.am index de73497..32cf927 100644 --- a/lustre/liblustre/Makefile.am +++ b/lustre/liblustre/Makefile.am @@ -65,7 +65,7 @@ liblustre_a_SOURCES = llite_lib.c llite_fid.c super.c namei.c rw.c file.c dir.c llite_lib.h liblustre.a : $(LUSTRE_LIBS) $(LND_LIBS) $(LNET_LIBS) $(SYSIO_LIBS) $(QUOTA_LIBS) - sh $(srcdir)/genlib.sh "$(SYSIO)" "$(LIBS)" "$(LND_LIBS)" "$(PTHREAD_LIBS)" "$(QUOTA_LIBS)" "$(CAP_LIBS)" + sh $(srcdir)/genlib.sh "$(SYSIO)" "$(LIBS)" "$(LND_LIBS)" "$(PTHREAD_LIBS)" "$(QUOTA_LIBS)" "$(CAP_LIBS)" "$(ZLIB)" EXTRA_DIST = genlib.sh diff --git a/lustre/liblustre/genlib.sh b/lustre/liblustre/genlib.sh index 2fc5bb5..dbe849f 100755 --- a/lustre/liblustre/genlib.sh +++ b/lustre/liblustre/genlib.sh @@ -24,6 +24,7 @@ LND_LIBS=$3 PTHREAD_LIBS=$4 QUOTA_LIBS=$5 CAP_LIBS=$6 +ZLIB=$7 if [ ! -f $SYSIO/lib/libsysio.a ]; then echo "ERROR: $SYSIO/lib/libsysio.a dosen't exist" diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index fc4ed66..86ab3b7 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -368,6 +368,20 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) if (sbi->ll_flags & LL_SBI_OSS_CAPA) data->ocd_connect_flags |= OBD_CONNECT_OSS_CAPA; + if (!OBD_FAIL_CHECK(OBD_FAIL_OSC_CONNECT_CKSUM)) { + /* OBD_CONNECT_CKSUM should always be set, even if checksums are + * disabled by default, because it can still be enabled on the + * fly via /proc. As a consequence, we still need to come to an + * agreement on the supported algorithms at connect time */ + data->ocd_connect_flags |= OBD_CONNECT_CKSUM; + + if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY)) + data->ocd_cksum_types = OBD_CKSUM_ADLER; + else + /* send the list of supported checksum types */ + data->ocd_cksum_types = OBD_CKSUM_ALL; + } + #ifdef HAVE_LRU_RESIZE_SUPPORT data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE; #endif diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 275d523..efc01d2 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2458,6 +2458,30 @@ static int filter_connect_internal(struct obd_export *exp, LASSERT(data->ocd_brw_size); } + if (data->ocd_connect_flags & OBD_CONNECT_CKSUM) { + __u32 cksum_types = data->ocd_cksum_types; + + /* The client set in ocd_cksum_types the checksum types it + * supports. We have to mask off the algorithms that we don't + * support */ + if (cksum_types & OBD_CKSUM_ALL) + data->ocd_cksum_types &= OBD_CKSUM_ALL; + else + data->ocd_cksum_types = OBD_CKSUM_CRC32; + + CDEBUG(D_RPCTRACE, "%s: cli %s supports cksum type %x, return " + "%x\n", exp->exp_obd->obd_name, + obd_export_nid2str(exp), cksum_types, + data->ocd_cksum_types); + } else { + /* This client does not support OBD_CONNECT_CKSUM + * fall back to CRC32 */ + CDEBUG(D_RPCTRACE, "%s: cli %s does not support " + "OBD_CONNECT_CKSUM, CRC32 will be used\n", + exp->exp_obd->obd_name, + obd_export_nid2str(exp)); + } + /* FIXME: Do the same with the MDS UUID and fsd_peeruuid. * FIXME: We don't strictly need the COMPAT flag for that, * FIXME: as fsd_peeruuid[0] will tell us if that is set. diff --git a/lustre/osc/lproc_osc.c b/lustre/osc/lproc_osc.c index 7980fd2..ba665a8 100644 --- a/lustre/osc/lproc_osc.c +++ b/lustre/osc/lproc_osc.c @@ -301,6 +301,62 @@ static int osc_wr_checksum(struct file *file, const char *buffer, return count; } +static int osc_rd_checksum_type(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct obd_device *obd = data; + int i, len =0; + DECLARE_CKSUM_NAME; + + if (obd == NULL) + return 0; + + for (i = 0; i < ARRAY_SIZE(cksum_name) && len < count; i++) { + if (((1 << i) & obd->u.cli.cl_supp_cksum_types) == 0) + continue; + if (obd->u.cli.cl_cksum_type == (1 << i)) + len += snprintf(page + len, count - len, "[%s] ", + cksum_name[i]); + else + len += snprintf(page + len, count - len, "%s ", + cksum_name[i]); + } + if (len < count) + len += sprintf(page + len, "\n"); + return len; +} + +static int osc_wd_checksum_type(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct obd_device *obd = data; + int i; + DECLARE_CKSUM_NAME; + char kernbuf[10]; + + if (obd == NULL) + return 0; + + if (count > sizeof(kernbuf) - 1) + return -EINVAL; + if (copy_from_user(kernbuf, buffer, count)) + return -EFAULT; + if (count > 0 && kernbuf[count - 1] == '\n') + kernbuf[count - 1] = '\0'; + else + kernbuf[count] = '\0'; + + for (i = 0; i < ARRAY_SIZE(cksum_name); i++) { + if (((1 << i) & obd->u.cli.cl_supp_cksum_types) == 0) + continue; + if (!strcmp(kernbuf, cksum_name[i])) { + obd->u.cli.cl_cksum_type = 1 << i; + return count; + } + } + return -EINVAL; +} + static int osc_rd_resend_count(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -353,6 +409,7 @@ static struct lprocfs_vars lprocfs_osc_obd_vars[] = { { "prealloc_next_id", osc_rd_prealloc_next_id, 0, 0 }, { "prealloc_last_id", osc_rd_prealloc_last_id, 0, 0 }, { "checksums", osc_rd_checksum, osc_wr_checksum, 0 }, + { "checksum_type", osc_rd_checksum_type, osc_wd_checksum_type, 0 }, { "resend_count", osc_rd_resend_count, osc_wr_resend_count, 0}, { 0 } }; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 06ec3dd..cda2381 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -974,12 +974,14 @@ static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2) } static obd_count osc_checksum_bulk(int nob, obd_count pg_count, - struct brw_page **pga, int opc) + struct brw_page **pga, int opc, + cksum_type_t cksum_type) { - __u32 cksum = ~0; + __u32 cksum; int i = 0; LASSERT (pg_count > 0); + cksum = init_checksum(cksum_type); while (nob > 0 && pg_count > 0) { unsigned char *ptr = cfs_kmap(pga[i]->pg); int off = pga[i]->off & ~CFS_PAGE_MASK; @@ -990,7 +992,7 @@ static obd_count osc_checksum_bulk(int nob, obd_count pg_count, if (i == 0 && opc == OST_READ && OBD_FAIL_CHECK(OBD_FAIL_OSC_CHECKSUM_RECEIVE)) memcpy(ptr + off, "bad1", min(4, nob)); - cksum = crc32_le(cksum, ptr + off, count); + cksum = compute_checksum(cksum, ptr + off, count, cksum_type); cfs_kunmap(pga[i]->pg); LL_CDEBUG_PAGE(D_PAGE, pga[i]->pg, "off %d checksum %x\n", off, cksum); @@ -1126,14 +1128,23 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, if (opc == OST_WRITE) { if (unlikely(cli->cl_checksum) && req->rq_flvr.sf_bulk_hash == BULK_HASH_ALG_NULL) { - body->oa.o_valid |= OBD_MD_FLCKSUM; + /* store cl_cksum_type in a local variable since + * it can be changed via lprocfs */ + cksum_type_t cksum_type = cli->cl_cksum_type; + + if ((body->oa.o_valid & OBD_MD_FLFLAGS) == 0) + oa->o_flags = body->oa.o_flags = 0; + body->oa.o_flags |= cksum_type_pack(cksum_type); + body->oa.o_valid |= OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; body->oa.o_cksum = osc_checksum_bulk(requested_nob, page_count, pga, - OST_WRITE); + OST_WRITE, + cksum_type); CDEBUG(D_PAGE, "checksum at write origin: %x\n", body->oa.o_cksum); /* save this in 'oa', too, for later checking */ - oa->o_valid |= OBD_MD_FLCKSUM; + oa->o_valid |= OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; + oa->o_flags |= cksum_type_pack(cksum_type); } else { /* clear out the checksum flag, in case this is a * resend but cl_checksum is no longer set. b=11238 */ @@ -1145,8 +1156,12 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, sizeof(__u32) * niocount); } else { if (unlikely(cli->cl_checksum) && - req->rq_flvr.sf_bulk_hash == BULK_HASH_ALG_NULL) - body->oa.o_valid |= OBD_MD_FLCKSUM; + req->rq_flvr.sf_bulk_hash == BULK_HASH_ALG_NULL) { + if ((body->oa.o_valid & OBD_MD_FLFLAGS) == 0) + body->oa.o_flags = 0; + body->oa.o_flags |= cksum_type_pack(cli->cl_cksum_type); + body->oa.o_valid |= OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; + } req_capsule_set_size(pill, &RMF_NIOBUF_REMOTE, RCL_SERVER, 0); /* 1 RC for the whole I/O */ } @@ -1172,21 +1187,31 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, } static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, - __u32 client_cksum, __u32 server_cksum, - int nob, obd_count page_count, - struct brw_page **pga) + __u32 client_cksum, __u32 server_cksum, int nob, + obd_count page_count, struct brw_page **pga, + cksum_type_t client_cksum_type) { __u32 new_cksum; char *msg; + cksum_type_t cksum_type; if (server_cksum == client_cksum) { CDEBUG(D_PAGE, "checksum %x confirmed\n", client_cksum); return 0; } - new_cksum = osc_checksum_bulk(nob, page_count, pga, OST_WRITE); + if (oa->o_valid & OBD_MD_FLFLAGS) + cksum_type = cksum_type_unpack(oa->o_flags); + else + cksum_type = OBD_CKSUM_CRC32; + + new_cksum = osc_checksum_bulk(nob, page_count, pga, OST_WRITE, + cksum_type); - if (new_cksum == server_cksum) + if (cksum_type != client_cksum_type) + msg = "the server did not use the checksum type specified in " + "the original request - likely a protocol problem"; + else if (new_cksum == server_cksum) msg = "changed on the client after we checksummed it - " "likely false positive due to mmap IO (bug 11742)"; else if (new_cksum == client_cksum) @@ -1206,8 +1231,9 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, oa->o_valid & OBD_MD_FLGROUP ? oa->o_gr : (__u64)0, pga[0]->off, pga[page_count-1]->off + pga[page_count-1]->count - 1); - CERROR("original client csum %x, server csum %x, client csum now %x\n", - client_cksum, server_cksum, new_cksum); + CERROR("original client csum %x (type %x), server csum %x (type %x), " + "client csum now %x\n", client_cksum, client_cksum_type, + server_cksum, cksum_type, new_cksum); return 1; } @@ -1243,7 +1269,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) if (rc < 0) RETURN(rc); - if (unlikely(aa->aa_oa->o_valid & OBD_MD_FLCKSUM)) + if (aa->aa_oa->o_valid & OBD_MD_FLCKSUM) client_cksum = aa->aa_oa->o_cksum; /* save for later */ osc_update_grant(cli, body); @@ -1255,13 +1281,11 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) } LASSERT(req->rq_bulk->bd_nob == aa->aa_requested_nob); - if (unlikely((aa->aa_oa->o_valid & OBD_MD_FLCKSUM) && - client_cksum && - check_write_checksum(&body->oa, peer, client_cksum, - body->oa.o_cksum, - aa->aa_requested_nob, - aa->aa_page_count, - aa->aa_ppga))) + if ((aa->aa_oa->o_valid & OBD_MD_FLCKSUM) && client_cksum && + check_write_checksum(&body->oa, peer, client_cksum, + body->oa.o_cksum, aa->aa_requested_nob, + aa->aa_page_count, aa->aa_ppga, + cksum_type_unpack(aa->aa_oa->o_flags))) RETURN(-EAGAIN); if (sptlrpc_cli_unwrap_bulk_write(req, req->rq_bulk)) @@ -1292,14 +1316,20 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) aa->aa_ppga)) GOTO(out, rc = -EAGAIN); - if (unlikely(body->oa.o_valid & OBD_MD_FLCKSUM)) { + if (body->oa.o_valid & OBD_MD_FLCKSUM) { static int cksum_counter; __u32 server_cksum = body->oa.o_cksum; char *via; char *router; + cksum_type_t cksum_type; + if (body->oa.o_valid & OBD_MD_FLFLAGS) + cksum_type = cksum_type_unpack(body->oa.o_flags); + else + cksum_type = OBD_CKSUM_CRC32; client_cksum = osc_checksum_bulk(rc, aa->aa_page_count, - aa->aa_ppga, OST_READ); + aa->aa_ppga, OST_READ, + cksum_type); if (peer->nid == req->rq_bulk->bd_sender) { via = router = ""; @@ -1332,8 +1362,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) aa->aa_ppga[aa->aa_page_count-1]->off + aa->aa_ppga[aa->aa_page_count-1]->count - 1); - CERROR("client %x, server %x\n", - client_cksum, server_cksum); + CERROR("client %x, server %x, cksum_type %x\n", + client_cksum, server_cksum, cksum_type); cksum_counter = 0; aa->aa_oa->o_cksum = client_cksum; rc = -EAGAIN; @@ -1421,7 +1451,7 @@ int osc_brw_redo_request(struct ptlrpc_request *request, CERROR("too many resend retries, returning error\n"); RETURN(-EIO); } - + DEBUG_REQ(D_ERROR, request, "redo for recoverable error"); /* body = lustre_msg_buf(request->rq_reqmsg, REQ_REC_OFF, sizeof(*body)); @@ -1439,7 +1469,7 @@ int osc_brw_redo_request(struct ptlrpc_request *request, RETURN(rc); client_obd_list_lock(&aa->aa_cli->cl_loi_list_lock); - + list_for_each_entry(oap, &aa->aa_oaps, oap_rpc_item) { if (oap->oap_request != NULL) { LASSERTF(request == oap->oap_request, @@ -1447,7 +1477,7 @@ int osc_brw_redo_request(struct ptlrpc_request *request, request, oap->oap_request); if (oap->oap_interrupted) { client_obd_list_unlock(&aa->aa_cli->cl_loi_list_lock); - ptlrpc_req_finished(new_req); + ptlrpc_req_finished(new_req); RETURN(-EINTR); } } diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index a442e09..e6a139c 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -470,11 +470,13 @@ static int get_per_page_niobufs(struct obd_ioobj *ioo, int nioo, return npages; } -static __u32 ost_checksum_bulk(struct ptlrpc_bulk_desc *desc, int opc) +static __u32 ost_checksum_bulk(struct ptlrpc_bulk_desc *desc, int opc, + cksum_type_t cksum_type) { - __u32 cksum = ~0; + __u32 cksum; int i; + cksum = init_checksum(cksum_type); for (i = 0; i < desc->bd_iov_count; i++) { struct page *page = desc->bd_iov[i].kiov_page; int off = desc->bd_iov[i].kiov_offset & ~CFS_PAGE_MASK; @@ -486,7 +488,7 @@ static __u32 ost_checksum_bulk(struct ptlrpc_bulk_desc *desc, int opc) if (i == 0 && opc == OST_WRITE && OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_RECEIVE)) memcpy(ptr, "bad3", min(4, len)); - cksum = crc32_le(cksum, ptr, len); + cksum = compute_checksum(cksum, ptr, len, cksum_type); /* corrupt the data after we compute the checksum, to * simulate an OST->client data error */ if (i == 0 && opc == OST_READ && @@ -810,9 +812,14 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) } } - if (unlikely(body->oa.o_valid & OBD_MD_FLCKSUM)) { - body->oa.o_cksum = ost_checksum_bulk(desc, OST_READ); - body->oa.o_valid = OBD_MD_FLCKSUM; + if (body->oa.o_valid & OBD_MD_FLCKSUM) { + cksum_type_t cksum_type = OBD_CKSUM_CRC32; + + if (body->oa.o_valid & OBD_MD_FLFLAGS) + cksum_type = cksum_type_unpack(body->oa.o_flags); + body->oa.o_flags = cksum_type_pack(cksum_type); + body->oa.o_valid = OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; + body->oa.o_cksum = ost_checksum_bulk(desc, OST_READ, cksum_type); CDEBUG(D_PAGE,"checksum at read origin: %x\n",body->oa.o_cksum); } else { body->oa.o_valid = 0; @@ -931,7 +938,8 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) int size[3] = { sizeof(struct ptlrpc_body), sizeof(*body) }; int objcount, niocount, npages; int rc, swab, i, j; - obd_count client_cksum, server_cksum = 0; + obd_count client_cksum = 0, server_cksum = 0; + cksum_type_t cksum_type = OBD_CKSUM_CRC32; int no_reply = 0; ENTRY; @@ -1060,7 +1068,11 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) ost_prolong_locks(exp, ioo, pp_rnb, LCK_PW); /* obd_preprw clobbers oa->valid, so save what we need */ - client_cksum = body->oa.o_valid & OBD_MD_FLCKSUM ? body->oa.o_cksum : 0; + if (body->oa.o_valid & OBD_MD_FLCKSUM) { + client_cksum = body->oa.o_cksum; + if (body->oa.o_valid & OBD_MD_FLFLAGS) + cksum_type = cksum_type_unpack(body->oa.o_flags); + } /* Because we already sync grant info with client when reconnect, * grant info will be cleared for resent req, then fed_grant and @@ -1124,8 +1136,10 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) if (unlikely(client_cksum != 0 && rc == 0)) { static int cksum_counter; - server_cksum = ost_checksum_bulk(desc, OST_WRITE); - repbody->oa.o_valid |= OBD_MD_FLCKSUM; + repbody->oa.o_valid |= OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; + repbody->oa.o_flags &= ~OBD_FL_CKSUM_ALL; + repbody->oa.o_flags |= cksum_type_pack(cksum_type); + server_cksum = ost_checksum_bulk(desc, OST_WRITE, cksum_type); repbody->oa.o_cksum = server_cksum; cksum_counter++; if (unlikely(client_cksum != server_cksum)) { @@ -1144,7 +1158,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) objcount, ioo, npages, local_nb, oti, rc); if (unlikely(client_cksum != server_cksum && rc == 0)) { - int new_cksum = ost_checksum_bulk(desc, OST_WRITE); + int new_cksum = ost_checksum_bulk(desc, OST_WRITE, cksum_type); char *msg; char *via; char *router; diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c index 26695b4..c570f12 100644 --- a/lustre/ptlrpc/import.c +++ b/lustre/ptlrpc/import.c @@ -792,6 +792,38 @@ finish: newer : older, LUSTRE_VERSION_STRING); } + if (ocd->ocd_connect_flags & OBD_CONNECT_CKSUM) { + /* We sent to the server ocd_cksum_types with bits set + * for algorithms we understand. The server masked off + * the checksum types it doesn't support */ + if ((ocd->ocd_cksum_types & OBD_CKSUM_ALL) == 0) { + LCONSOLE_WARN("The negotiation of the checksum " + "alogrithm to use with server %s " + "failed (%x/%x), disabling " + "checksums\n", + obd2cli_tgt(imp->imp_obd), + ocd->ocd_cksum_types, + OBD_CKSUM_ALL); + cli->cl_checksum = 0; + cli->cl_supp_cksum_types = OBD_CKSUM_CRC32; + cli->cl_cksum_type = OBD_CKSUM_CRC32; + } else { + cli->cl_supp_cksum_types = ocd->ocd_cksum_types; + + if (ocd->ocd_cksum_types & OSC_DEFAULT_CKSUM) + cli->cl_cksum_type = OSC_DEFAULT_CKSUM; + else if (ocd->ocd_cksum_types & OBD_CKSUM_ADLER) + cli->cl_cksum_type = OBD_CKSUM_ADLER; + else + cli->cl_cksum_type = OBD_CKSUM_CRC32; + } + } else { + /* The server does not support OBD_CONNECT_CKSUM. + * Enforce CRC32 for backward compatibility*/ + cli->cl_supp_cksum_types = OBD_CKSUM_CRC32; + cli->cl_cksum_type = OBD_CKSUM_CRC32; + } + if (ocd->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) { cli->cl_max_pages_per_rpc = ocd->ocd_brw_size >> CFS_PAGE_SHIFT; diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index da2f5e0..d222812 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -1721,9 +1721,9 @@ void lustre_swab_connect(struct obd_connect_data *ocd) __swab32s(&ocd->ocd_nllg); __swab64s(&ocd->ocd_transno); __swab32s(&ocd->ocd_group); + __swab32s(&ocd->ocd_cksum_types); CLASSERT(offsetof(typeof(*ocd), padding1) != 0); CLASSERT(offsetof(typeof(*ocd), padding2) != 0); - CLASSERT(offsetof(typeof(*ocd), padding3) != 0); } void lustre_swab_obdo (struct obdo *o) diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 6fe15c5..090fa86 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -437,18 +437,18 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obd_connect_data, ocd_group)); LASSERTF((int)sizeof(((struct obd_connect_data *)0)->ocd_group) == 4, " found %lld\n", (long long)(int)sizeof(((struct obd_connect_data *)0)->ocd_group)); - LASSERTF((int)offsetof(struct obd_connect_data, padding1) == 52, " found %lld\n", + LASSERTF((int)offsetof(struct obd_connect_data, ocd_cksum_types) == 52, " found %lld\n", + (long long)(int)offsetof(struct obd_connect_data, ocd_cksum_types)); + LASSERTF((int)sizeof(((struct obd_connect_data *)0)->ocd_cksum_types) == 4, " found %lld\n", + (long long)(int)sizeof(((struct obd_connect_data *)0)->ocd_cksum_types)); + LASSERTF((int)offsetof(struct obd_connect_data, padding1) == 56, " found %lld\n", (long long)(int)offsetof(struct obd_connect_data, padding1)); - LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding1) == 4, " found %lld\n", + LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding1) == 8, " found %lld\n", (long long)(int)sizeof(((struct obd_connect_data *)0)->padding1)); - LASSERTF((int)offsetof(struct obd_connect_data, padding2) == 56, " found %lld\n", + LASSERTF((int)offsetof(struct obd_connect_data, padding2) == 64, " found %lld\n", (long long)(int)offsetof(struct obd_connect_data, padding2)); LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding2) == 8, " found %lld\n", (long long)(int)sizeof(((struct obd_connect_data *)0)->padding2)); - LASSERTF((int)offsetof(struct obd_connect_data, padding3) == 64, " found %lld\n", - (long long)(int)offsetof(struct obd_connect_data, padding3)); - LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding3) == 8, " found %lld\n", - (long long)(int)sizeof(((struct obd_connect_data *)0)->padding3)); CLASSERT(OBD_CONNECT_RDONLY == 0x00000001ULL); CLASSERT(OBD_CONNECT_INDEX == 0x00000002ULL); CLASSERT(OBD_CONNECT_GRANT == 0x00000008ULL); @@ -618,6 +618,11 @@ void lustre_assert_wire_constants(void) CLASSERT(OBD_FL_DEBUG_CHECK == (0x00000040)); CLASSERT(OBD_FL_NO_USRQUOTA == (0x00000100)); CLASSERT(OBD_FL_NO_GRPQUOTA == (0x00000200)); + CLASSERT(OBD_FL_TRUNCLOCK == (0x00000800)); + CLASSERT(OBD_FL_CKSUM_CRC32 == (0x00001000)); + CLASSERT(OBD_FL_CKSUM_ADLER == (0x00002000)); + CLASSERT(OBD_CKSUM_CRC32 == (0x00000001)); + CLASSERT(OBD_CKSUM_ADLER == (0x00000002)); /* Checks for struct lov_mds_md_v1 */ LASSERTF((int)sizeof(struct lov_mds_md_v1) == 32, " found %lld\n", diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 84294d0..f74f9e5 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -3270,10 +3270,22 @@ set_checksums() for f in $LPROC/osc/*/checksums; do echo $1 >> $f done - return 0 } +export ORIG_CSUM_TYPE="" +CKSUM_TYPES=${CKSUM_TYPES:-"crc32 adler"} +set_checksum_type() +{ + [ "$ORIG_CSUM_TYPE" ] || \ + ORIG_CSUM_TYPE=`sed 's/.*\[\(.*\)\].*/\1/g' \ + $LPROC/osc/*osc-[^mM]*/checksum_type | head -n1` + for f in $LPROC/osc/*osc-*/checksum_type; do + echo $1 > $f + done + log "set checksum type to $1" + return 0 +} F77_TMP=$TMP/f77-temp F77SZ=8 setup_f77() { @@ -3303,13 +3315,17 @@ run_test 77b "checksum error on client write ====================" test_77c() { # bug 10889 [ ! -f $DIR/f77b ] && skip "requires 77b - skipping" && return - cancel_lru_locks osc - #define OBD_FAIL_OSC_CHECKSUM_RECEIVE 0x408 - sysctl -w lustre.fail_loc=0x80000408 set_checksums 1 - cmp $F77_TMP $DIR/f77b || error "file compare failed" - sysctl -w lustre.fail_loc=0 + for algo in $CKSUM_TYPES; do + cancel_lru_locks osc + set_checksum_type $algo + #define OBD_FAIL_OSC_CHECKSUM_RECEIVE 0x408 + sysctl -w lustre.fail_loc=0x80000408 + cmp $F77_TMP $DIR/f77b || error "file compare failed" + sysctl -w lustre.fail_loc=0 + done set_checksums 0 + set_checksum_type $ORIG_CSUM_TYPE } run_test 77c "checksum error on client read ===================" @@ -3338,12 +3354,17 @@ test_77e() { # bug 10889 run_test 77e "checksum error on OST direct read ================" test_77f() { # bug 10889 - #define OBD_FAIL_OSC_CHECKSUM_SEND 0x409 - sysctl -w lustre.fail_loc=0x409 set_checksums 1 - directio write $DIR/f77 0 $F77SZ $((1024 * 1024)) && \ - error "direct write succeeded" - sysctl -w lustre.fail_loc=0 + for algo in $CKSUM_TYPES; do + cancel_lru_locks osc + set_checksum_type $algo + #define OBD_FAIL_OSC_CHECKSUM_SEND 0x409 + sysctl -w lustre.fail_loc=0x409 + directio write $DIR/f77 0 $F77SZ $((1024 * 1024)) && \ + error "direct write succeeded" + sysctl -w lustre.fail_loc=0 + done + set_checksum_type $ORIG_CSUM_TYPE set_checksums 0 } run_test 77f "repeat checksum error on write (expect error) ====" @@ -3376,6 +3397,32 @@ test_77h() { # bug 10889 } run_test 77h "checksum error on OST read =======================" +test_77i() { # bug 13805 + #define OBD_FAIL_OSC_CONNECT_CKSUM 0x40b + sysctl -w lustre.fail_loc=0x40b + remount_client $MOUNT + sysctl -w lustre.fail_loc=0 + for f in $LPROC/osc/*osc-[^mM]*/checksum_type; do + algo=`sed 's/.*\[\(.*\)\].*/\1/g' $f` + [ "$algo" = "crc32" ] || error "algo set to $algo instead of crc32" + done + remount_client $MOUNT +} +run_test 77i "client not supporting OSD_CONNECT_CKSUM ==========" + +test_77j() { # bug 13805 + #define OBD_FAIL_OSC_CKSUM_ADLER_ONLY 0x40c + sysctl -w lustre.fail_loc=0x40c + remount_client $MOUNT + sysctl -w lustre.fail_loc=0 + for f in $LPROC/osc/*osc-[^mM]*/checksum_type; do + algo=`sed 's/.*\[\(.*\)\].*/\1/g' $f` + [ "$algo" = "adler" ] || error "algo set to $algo instead of adler" + done + remount_client $MOUNT +} +run_test 77j "client only supporting ADLER32 ====================" + [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true rm -f $F77_TMP unset F77_TMP diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index d059bcb..e6bb07a 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -955,6 +955,12 @@ switch_identity() { fi } +remount_client() +{ + zconf_umount `hostname` $1 || error "umount failed" + zconf_mount `hostname` $1 || error "mount failed" +} + setupall() { load_modules init_gss diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index c7ceb3f..b65f4ab 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -174,9 +174,9 @@ static void check_obd_connect_data(void) CHECK_MEMBER(obd_connect_data, ocd_nllg); CHECK_MEMBER(obd_connect_data, ocd_transno); CHECK_MEMBER(obd_connect_data, ocd_group); + CHECK_MEMBER(obd_connect_data, ocd_cksum_types); CHECK_MEMBER(obd_connect_data, padding1); CHECK_MEMBER(obd_connect_data, padding2); - CHECK_MEMBER(obd_connect_data, padding3); CHECK_CDEFINE(OBD_CONNECT_RDONLY); CHECK_CDEFINE(OBD_CONNECT_INDEX); @@ -283,6 +283,11 @@ check_obdo(void) CHECK_CDEFINE(OBD_FL_DEBUG_CHECK); CHECK_CDEFINE(OBD_FL_NO_USRQUOTA); CHECK_CDEFINE(OBD_FL_NO_GRPQUOTA); + CHECK_CDEFINE(OBD_FL_TRUNCLOCK); + CHECK_CDEFINE(OBD_FL_CKSUM_CRC32); + CHECK_CDEFINE(OBD_FL_CKSUM_ADLER); + CHECK_CDEFINE(OBD_CKSUM_CRC32); + CHECK_CDEFINE(OBD_CKSUM_ADLER); } static void diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index e963f86..e067dab 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -455,18 +455,18 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obd_connect_data, ocd_group)); LASSERTF((int)sizeof(((struct obd_connect_data *)0)->ocd_group) == 4, " found %lld\n", (long long)(int)sizeof(((struct obd_connect_data *)0)->ocd_group)); - LASSERTF((int)offsetof(struct obd_connect_data, padding1) == 52, " found %lld\n", + LASSERTF((int)offsetof(struct obd_connect_data, ocd_cksum_types) == 52, " found %lld\n", + (long long)(int)offsetof(struct obd_connect_data, ocd_cksum_types)); + LASSERTF((int)sizeof(((struct obd_connect_data *)0)->ocd_cksum_types) == 4, " found %lld\n", + (long long)(int)sizeof(((struct obd_connect_data *)0)->ocd_cksum_types)); + LASSERTF((int)offsetof(struct obd_connect_data, padding1) == 56, " found %lld\n", (long long)(int)offsetof(struct obd_connect_data, padding1)); - LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding1) == 4, " found %lld\n", + LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding1) == 8, " found %lld\n", (long long)(int)sizeof(((struct obd_connect_data *)0)->padding1)); - LASSERTF((int)offsetof(struct obd_connect_data, padding2) == 56, " found %lld\n", + LASSERTF((int)offsetof(struct obd_connect_data, padding2) == 64, " found %lld\n", (long long)(int)offsetof(struct obd_connect_data, padding2)); LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding2) == 8, " found %lld\n", (long long)(int)sizeof(((struct obd_connect_data *)0)->padding2)); - LASSERTF((int)offsetof(struct obd_connect_data, padding3) == 64, " found %lld\n", - (long long)(int)offsetof(struct obd_connect_data, padding3)); - LASSERTF((int)sizeof(((struct obd_connect_data *)0)->padding3) == 8, " found %lld\n", - (long long)(int)sizeof(((struct obd_connect_data *)0)->padding3)); CLASSERT(OBD_CONNECT_RDONLY == 0x00000001ULL); CLASSERT(OBD_CONNECT_INDEX == 0x00000002ULL); CLASSERT(OBD_CONNECT_GRANT == 0x00000008ULL); @@ -636,7 +636,12 @@ void lustre_assert_wire_constants(void) CLASSERT(OBD_FL_DEBUG_CHECK == (0x00000040)); CLASSERT(OBD_FL_NO_USRQUOTA == (0x00000100)); CLASSERT(OBD_FL_NO_GRPQUOTA == (0x00000200)); - + CLASSERT(OBD_FL_TRUNCLOCK == (0x00000800)); + CLASSERT(OBD_FL_CKSUM_CRC32 == (0x00001000)); + CLASSERT(OBD_FL_CKSUM_ADLER == (0x00002000)); + CLASSERT(OBD_CKSUM_CRC32 == (0x00000001)); + CLASSERT(OBD_CKSUM_ADLER == (0x00000002)); + /* Checks for struct lov_mds_md_v1 */ LASSERTF((int)sizeof(struct lov_mds_md_v1) == 32, " found %lld\n", (long long)(int)sizeof(struct lov_mds_md_v1)); -- 1.8.3.1