From 350abc09880fc4cc1085f462258bf6e0f7b933f2 Mon Sep 17 00:00:00 2001 From: wangdi Date: Fri, 5 Aug 2005 14:45:34 +0000 Subject: [PATCH] Branch: HEAD land crypto api --- lustre/autoconf/lustre-core.m4 | 2 + lustre/cmobd/cm_mds_reint.c | 2 +- lustre/cobd/cache_obd.c | 5 +- lustre/include/liblustre.h | 2 + lustre/include/linux/lustre_fsfilt.h | 3 +- lustre/include/linux/lustre_gs.h | 161 +++++ lustre/include/linux/lustre_idl.h | 51 +- lustre/include/linux/lustre_lite.h | 5 +- lustre/include/linux/lustre_mds.h | 4 +- lustre/include/linux/lustre_net.h | 14 +- lustre/include/linux/obd.h | 14 +- lustre/include/linux/obd_class.h | 5 +- lustre/include/lustre/lustre_user.h | 4 + .../patches/ext3-mballoc2-2.6.10-fc3.patch | 2 +- lustre/kernel_patches/series/2.6-fc3-uml.series | 2 +- lustre/ldlm/ldlm_lib.c | 6 + lustre/ldlm/ldlm_resource.c | 1 + lustre/liblustre/llite_lib.h | 1 + lustre/llite/Makefile.in | 3 +- lustre/llite/dcache.c | 19 +- lustre/llite/dir.c | 27 +- lustre/llite/file.c | 58 +- lustre/llite/llite_close.c | 1 + lustre/llite/llite_gs.c | 791 +++++++++++++++++++++ lustre/llite/llite_internal.h | 145 +++- lustre/llite/llite_lib.c | 492 +++++++------ lustre/llite/namei.c | 19 +- lustre/llite/rw.c | 41 +- lustre/lmv/lmv_obd.c | 15 +- lustre/lov/lov_obd.c | 3 +- lustre/lvfs/fsfilt_ext3.c | 11 + lustre/mdc/mdc_internal.h | 6 +- lustre/mdc/mdc_lib.c | 22 +- lustre/mdc/mdc_locks.c | 39 +- lustre/mdc/mdc_reint.c | 7 +- lustre/mdc/mdc_request.c | 140 ++-- lustre/mds/handler.c | 129 ++-- lustre/mds/mds_internal.h | 10 +- lustre/mds/mds_lib.c | 149 +++- lustre/mds/mds_open.c | 27 +- lustre/mds/mds_reint.c | 34 +- lustre/obdclass/obd_config.c | 22 +- lustre/obdfilter/filter.c | 4 +- lustre/obdfilter/filter_io.c | 5 + lustre/osc/osc_create.c | 43 ++ lustre/osc/osc_request.c | 37 +- lustre/ptlrpc/import.c | 1 + lustre/ptlrpc/pack_generic.c | 47 +- lustre/ptlrpc/ptlrpc_module.c | 3 + lustre/sec/Makefile.in | 2 +- lustre/sec/autoMakefile.am | 2 +- lustre/sec/gks/Makefile.in | 6 + lustre/sec/gks/Makefile.mk | 11 + lustre/sec/gks/autoMakefile.am | 13 + lustre/sec/gks/gks_client.c | 201 ++++++ lustre/sec/gks/gks_internal.h | 46 ++ lustre/sec/gks/gks_server.c | 503 +++++++++++++ lustre/sec/gks/lproc_gks.c | 38 + lustre/smfs/fsfilt.c | 6 + lustre/smfs/mds_kml.c | 5 +- lustre/tests/cfg/lmv.sh | 2 + lustre/tests/lgs.sh | 65 ++ lustre/tests/sanity-crypto.sh | 112 +++ lustre/tests/test-framework.sh | 22 +- lustre/utils/lconf | 127 +++- lustre/utils/lctl.c | 9 +- lustre/utils/lmc | 71 +- lustre/utils/lustre_cfg.c | 2 +- lustre/utils/obd.c | 98 +++ lustre/utils/obdctl.h | 4 +- 70 files changed, 3522 insertions(+), 457 deletions(-) create mode 100644 lustre/include/linux/lustre_gs.h create mode 100644 lustre/llite/llite_gs.c create mode 100644 lustre/sec/gks/Makefile.in create mode 100644 lustre/sec/gks/Makefile.mk create mode 100644 lustre/sec/gks/autoMakefile.am create mode 100644 lustre/sec/gks/gks_client.c create mode 100644 lustre/sec/gks/gks_internal.h create mode 100644 lustre/sec/gks/gks_server.c create mode 100644 lustre/sec/gks/lproc_gks.c create mode 100755 lustre/tests/lgs.sh create mode 100755 lustre/tests/sanity-crypto.sh diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index cb91310..8012e79 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -580,6 +580,8 @@ lustre/sec/Makefile lustre/sec/autoMakefile lustre/sec/gss/Makefile lustre/sec/gss/autoMakefile +lustre/sec/gks/Makefile +lustre/sec/gks/autoMakefile lustre/smfs/Makefile lustre/smfs/autoMakefile lustre/snapfs/Makefile diff --git a/lustre/cmobd/cm_mds_reint.c b/lustre/cmobd/cm_mds_reint.c index decd816..c51923e 100644 --- a/lustre/cmobd/cm_mds_reint.c +++ b/lustre/cmobd/cm_mds_reint.c @@ -125,7 +125,7 @@ static int cmobd_reint_setattr(struct obd_device *obd, void *record) ea2len = ea2 ? msg->buflens[2] : 0; rc = md_setattr(cmobd->master_exp, op_data, &iattr, - ea1, ea1len, ea2, ea2len, &req); + ea1, ea1len, ea2, ea2len, NULL, 0, &req); OBD_FREE(op_data, sizeof(*op_data)); if (req) diff --git a/lustre/cobd/cache_obd.c b/lustre/cobd/cache_obd.c index d7007ba..ab37de8 100644 --- a/lustre/cobd/cache_obd.c +++ b/lustre/cobd/cache_obd.c @@ -1116,7 +1116,8 @@ static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data, static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data, struct iattr *iattr, void *ea, int ealen, void *ea2, - int ea2len, struct ptlrpc_request **request) + int ea2len, void *ea3, int ea3len, + struct ptlrpc_request **request) { struct obd_device *obd = class_exp2obd(exp); struct obd_export *cobd_exp; @@ -1128,7 +1129,7 @@ static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data, } cobd_exp = cobd_get_exp(obd); return md_setattr(cobd_exp, data, iattr, ea, - ealen, ea2, ea2len, request); + ealen, ea2, ea2len, ea3, ea3len, request); } static int cobd_md_readpage(struct obd_export *exp, diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index 72fb1aa..56ed008 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -499,6 +499,8 @@ struct lustre_intent_data { void *it_data; int it_lock_mode; int it_int_flags; + void *it_key; + int it_key_size; }; #define LUSTRE_IT(it) ((struct lustre_intent_data *)((it)->d.fs_data)) diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index 5c9ecd07..86a6d76 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -44,7 +44,8 @@ enum ea_type { EA_LOV = (1 << 0), EA_MEA = (1 << 1), EA_SID = (1 << 2), - EA_MID = (1 << 3) + EA_MID = (1 << 3), + EA_KEY = (1 << 4) }; struct fsfilt_operations { diff --git a/lustre/include/linux/lustre_gs.h b/lustre/include/linux/lustre_gs.h new file mode 100644 index 0000000..d155efd --- /dev/null +++ b/lustre/include/linux/lustre_gs.h @@ -0,0 +1,161 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2001-2003 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * GS data structures. + * See also lustre_idl.h for wire formats of requests. + * + */ + +#ifndef _LUSTRE_GS_H +#define _LUSTRE_GS_H + +#define LUSTRE_GKS_NAME "gks" +#define LUSTRE_GKT_NAME "gkt" +#define LUSTRE_GKC_NAME "gkc" + + +/*define gsk type*/ +#define NO_CRYPTO 0 +#define GKS_TYPE 1 +#define MKS_TYPE 2 + +struct crypto_ops_item { + struct crypto_helper_ops *cops; + struct list_head clist; + char *ctype; +}; + +#define DECRYPT_DATA 0x00000001 +#define ENCRYPT_DATA 0x00000002 +struct lustre_key { + struct crypto_key lk_ck; + atomic_t lk_refcount; + __u32 lk_key_type; + __u32 lk_flags; +}; + +static inline struct lustre_key * +lustre_key_get(struct lustre_key *lkey) +{ + if (lkey) { + atomic_inc(&lkey->lk_refcount); + } + return lkey; +} + + +static inline void +lustre_key_release(struct lustre_key *lkey) +{ + if (lkey && atomic_dec_and_test(&lkey->lk_refcount)) + kfree(lkey); +} + +#define SET_CRYPTO_FLAGS(flags, type, offset, width) \ +do { \ + flags &= ~(((1 << width) - 1) << offset); \ + flags |= (type & ((1 << width) - 1)) << offset; \ +} while(0) + +#define CPT_TYPE_OFFSET 0 +#define CPT_TYPE_WIDTH 2 +#define GKS_CRYPTO_TYPE 1 +#define MKS_CRYPTO_TYPE 2 + +#define SET_CRYPTO_TYPE(flags, type) \ +SET_CRYPTO_FLAGS(flags, type, CPT_TYPE_OFFSET, CPT_TYPE_WIDTH) + +#define IS_GKS_TYPE(flags) \ +(((flags >> CPT_TYPE_OFFSET) & ((1 << CPT_TYPE_WIDTH) - 1)) == GKS_CRYPTO_TYPE) + +#define IS_MKS_TYPE(flags) \ +(((flags >> CPT_TYPE_OFFSET) & ((1 << CPT_TYPE_WIDTH) - 1)) == MKS_CRYPTO_TYPE) + +#define CPT_ENCRYPT_OFFSET 2 +#define CPT_ENCRYPT_WIDTH 1 +#define ENABLE_ENCRYPT_FLAG 1 +#define DISABLE_ENCRYPT_FLAG 0 + +#define ENABLE_ENCRYPT(flag) \ +SET_CRYPTO_FLAGS(flag, ENABLE_ENCRYPT_FLAG, CPT_ENCRYPT_OFFSET, CPT_ENCRYPT_WIDTH) + +#define DISABLE_ENCRYPT(flag) \ +SET_CRYPTO_FLAGS(flag, DISABLE_ENCRYPT_FLAG, CPT_ENCRYPT_OFFSET, CPT_ENCRYPT_WIDTH) + +#define IS_ENABLE_ENCRYPT(flags) \ +(((flags >> CPT_ENCRYPT_OFFSET) & ((1 << CPT_ENCRYPT_WIDTH) - 1)) \ + == ENABLE_ENCRYPT_FLAG) + +#define CPT_DECRYPT_OFFSET 3 +#define CPT_DECRYPT_WIDTH 1 +#define ENABLE_DECRYPT_FLAG 1 +#define DISABLE_DECRYPT_FLAG 2 + +#define ENABLE_DECRYPT(flag) \ +SET_CRYPTO_FLAGS(flag, ENABLE_DECRYPT_FLAG, CPT_DECRYPT_OFFSET, CPT_DECRYPT_WIDTH) + +#define DISABLE_DECRYPT(flag) \ +SET_CRYPTO_FLAGS(flag, DISABLE_DECRYPT_FLAG, CPT_DECRYPT_OFFSET, CPT_DECRYPT_WIDTH) + +#define IS_ENABLE_DECRYPT(flags) \ +(((flags >> CPT_DECRYPT_OFFSET) & ((1 << CPT_DECRYPT_WIDTH) - 1)) \ + == ENABLE_DECRYPT_FLAG) + +#define CPT_DECRYPTED_OFFSET 4 +#define CPT_DECRYPTED_WIDTH 1 +#define DECRYPTED_FLAG 1 +#define ENCRYPTED_FLAG 0 + +#define SET_DECRYPTED(flag) \ +SET_CRYPTO_FLAGS(flag, DECRYPTED_FLAG, CPT_DECRYPTED_OFFSET, CPT_DECRYPTED_WIDTH) + +#define SET_UNDECRYPTED(flag) \ +SET_CRYPTO_FLAGS(flag, ENCRYPTED_FLAG, CPT_DECRYPTED_OFFSET, CPT_DECRYPTED_WIDTH) + +#define IS_DECRYPTED(flags) \ +(((flags >> CPT_DECRYPTED_OFFSET) & ((1 << CPT_DECRYPTED_WIDTH) - 1)) \ + == DECRYPTED_FLAG) + + + +#define MD_KEY_MAGIC 0x19760218 +struct crypto_key_md { + struct crypto_key md_ck; + __u32 md_magic; +}; + +struct key_parms { + struct key_context *context; + struct key_perm *perm; + int context_size; + int perm_size; +}; + +static inline int crypto_kcontext_size(int acl_count) +{ + return (sizeof(struct key_context) + acl_count * + sizeof(struct posix_acl_entry)); +} +static inline int crypto_kperm_size(int acl_count) +{ + return (sizeof(struct key_perm) + acl_count * + sizeof(struct posix_acl_entry)); +} +#endif /*LUSTRE_GS_H*/ diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index e26217c..030199a 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -61,6 +61,7 @@ # include # include /* for strncpy, below */ # include /* to check for FMODE_EXEC, dev_t, lest we redefine */ +# include #else #ifdef __CYGWIN__ # include @@ -117,6 +118,8 @@ #define MGMT_REPLY_PORTAL 25 #define MGMT_CLI_REQUEST_PORTAL 26 #define MGMT_CLI_REPLY_PORTAL 27 +#define GKS_REQUEST_PORTAL 28 +#define GKC_REPLY_PORTAL 29 #define SVC_KILLED 1 #define SVC_EVENT 2 @@ -141,6 +144,7 @@ #define LUSTRE_DLM_VERSION 0x00040000 #define LUSTRE_LOG_VERSION 0x00050000 #define LUSTRE_PBD_VERSION 0x00060000 +#define LUSTRE_GKS_VERSION 0x00070000 struct lustre_handle { __u64 cookie; @@ -417,13 +421,14 @@ struct lov_mds_md_v0 { /* LOV EA mds/wire data (little-endian) */ #define OBD_MD_FLXATTRLIST (0x0000000200000000LL) /* user xattr list */ #define OBD_MD_FLACL (0x0000000400000000LL) /* acl */ #define OBD_MD_FLRMTACL (0x0000000800000000LL) /* remote acl */ +#define OBD_MD_FLKEY (0x0000001000000000LL) /* mds key extended attributes */ #define OBD_MD_FLNOTOBD (~(OBD_MD_FLBLOCKS | OBD_MD_LINKNAME | \ OBD_MD_FLEASIZE | OBD_MD_FLHANDLE | \ OBD_MD_FLCKSUM | OBD_MD_FLQOS | \ OBD_MD_FLOSCOPQ | OBD_MD_FLCOOKIE | \ OBD_MD_FLXATTR | OBD_MD_FLXATTRLIST | \ - OBD_MD_FLACL | OBD_MD_MDS)) + OBD_MD_FLACL | OBD_MD_FLKEY | OBD_MD_MDS)) static inline struct lustre_handle *obdo_handle(struct obdo *oa) { @@ -687,6 +692,7 @@ struct lustre_md { struct mea *mea; struct posix_acl *posix_acl; struct mds_remote_perm *remote_perm; + struct lustre_key *key; }; void lustre_swab_remote_perm(struct mds_remote_perm *p); @@ -735,6 +741,8 @@ struct mds_rec_setattr { #define ATTR_EA 0x00040000 #define ATTR_EA_RM 0x00080000 #define ATTR_EA_CMOBD 0x00100000 +#define ATTR_KEY 0x00200000 +#define ATTR_MAC 0x00400000 extern void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa); #ifndef FMODE_READ @@ -752,6 +760,7 @@ extern void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa); #define MDS_OPEN_DIRECTORY 00200000 #define MDS_OPEN_DELAY_CREATE 0100000000 /* delay initial object create */ +#define MDS_OPEN_HAS_KEY 01000000000 /* just set the EA the obj exist */ #define MDS_OPEN_HAS_EA 010000000000 /* specify object create pattern */ #define MDS_OPEN_HAS_OBJS 020000000000 /* just set the EA the obj exist */ @@ -764,6 +773,8 @@ struct mds_rec_create { struct lustre_id cr_replayid; __u64 cr_time; __u64 cr_rdev; + __u64 cr_enkey; + __u64 cr_mac; }; extern void lustre_swab_mds_rec_create (struct mds_rec_create *cr); @@ -1189,11 +1200,47 @@ typedef enum { SEC_LAST_OPC } sec_cmd_t; #define SEC_FIRST_OPC SEC_INIT +/* GS opcodes*/ +typedef enum { + GKS_CONNECT = 700, + GKS_DISCONNECT = 701, + GKS_GET_KEY = 702, + GKS_DECRYPT_KEY = 703, + GKS_GET_MAC = 704, +} gks_cmd_t; + +#ifdef __KERNEL__ +#define KEY_SIZE 16 +#define MAC_SIZE 16 + +struct crypto_key { + __u8 ck_mac[MAC_SIZE]; + __u8 ck_key[KEY_SIZE]; + __u32 ck_type; +}; + +struct key_perm { + uid_t kp_uid; + gid_t kp_gid; + __u32 kp_mode; + __u32 kp_acl_count; + struct posix_acl_entry kp_acls[0]; +}; +struct key_context { + struct crypto_key kc_ck; + __u32 kc_command; + __u32 kc_valid; + struct key_perm kc_perm; +}; +typedef int (*crypt_cb_t)(struct page *page, __u64 offset, __u64 count, + int flags); +extern void lustre_swab_key_context (struct key_context *kctxt); +extern void lustre_swab_key_perms (struct key_perm *kperm); +#endif /*for define __KERNEL*/ extern void lustre_swab_lustre_id(struct lustre_id *id); extern void lustre_swab_lov_desc(struct lov_desc *desc); extern void lustre_swab_lustre_stc(struct lustre_stc *stc); extern void lustre_swab_lustre_fid(struct lustre_fid *fid); extern void lustre_swab_mds_status_req(struct mds_status_req *r); - #endif diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index b0ff350..66362f3 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -114,9 +114,9 @@ struct ll_inode_info { __u64 lli_open_fd_write_count; struct obd_client_handle *lli_mds_exec_och; __u64 lli_open_fd_exec_count; - struct posix_acl *lli_posix_acl; struct remote_acl *lli_remote_acl; + struct lustre_key *lli_key_info; }; // FIXME: replace the name of this with LL_I to conform to kernel stuff @@ -177,6 +177,9 @@ struct lustre_intent_data { __u64 it_lock_handle; void *it_data; int it_lock_mode; + int it_int_flags; + void *it_key; + int it_key_size; }; #define LUSTRE_IT(it) ((struct lustre_intent_data *)((it)->d.fs_data)) diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index dcbda8a..63730a9 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -65,6 +65,8 @@ struct mds_update_record { void *ur_eadata; int ur_ea2datalen; void *ur_ea2data; + int ur_ea3datalen; + void *ur_ea3data; int ur_cookielen; /* obsolete? */ struct llog_cookie *ur_logcookies; /* obsolete? */ struct iattr ur_iattr; @@ -335,7 +337,7 @@ int mdc_getattr_lock(struct obd_export *exp, struct lustre_id *id, unsigned int ea_size, struct ptlrpc_request **request); int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data, struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len, - struct ptlrpc_request **request); + void *ea3, int ea3len, struct ptlrpc_request **request); int mdc_open(struct obd_export *exp, obd_id ino, int type, int flags, struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, struct ptlrpc_request **); diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index e2bb14a..0e47bd7 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -133,6 +133,16 @@ OST_MAX_THREADS), 2UL) #define OST_NBUFS (64 * smp_num_cpus) #define OST_BUFSIZE (8 * 1024) +/*GSS service parameters*/ +#define GKS_NBUFS (64 * smp_num_cpus) +#define GKS_BUFSIZE (8 * 1024) +#define GKT_MAX_THREADS 32UL +#define GKT_NUM_THREADS max(min_t(unsigned long, num_physpages / 8192, \ + GKT_MAX_THREADS), 2UL) + +#define GKS_MAXREQSIZE (5 * 1024) + + /* OST_MAXREQSIZE ~= 1640 bytes = * lustre_msg + obdo + 16 * obd_ioobj + 64 * niobuf_remote * @@ -750,7 +760,8 @@ void lustre_init_msg (struct lustre_msg *msg, int count, int *lens, char **bufs); void *mdc_setattr_pack(struct lustre_msg *msg, int offset, struct mdc_op_data *data, struct iattr *iattr, - void *ea, int ealen, void *ea2, int ea2len); + void *ea, int ealen, void *ea2, int ea2len, + void *ea3, int ea3len); void *mdc_create_pack(struct lustre_msg *msg, int offset, struct mdc_op_data *op_data, __u32 mode, __u64 rdev, const void *data, int datalen); @@ -762,6 +773,7 @@ void *mdc_rename_pack(struct lustre_msg *msg, int offset, struct mdc_op_data *data, const char *old, int oldlen, const char *new, int newlen); +__u32 mds_pack_open_flags(__u32 flags); /* lustre id helper functions and macros. */ static inline diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 7a64c7a..5d1d006 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -410,6 +410,7 @@ struct mds_obd { spinlock_t mds_denylist_lock; struct list_head mds_denylist; struct semaphore mds_create_sem; + int mds_crypto_type; }; struct echo_obd { @@ -538,6 +539,16 @@ struct lmv_obd { struct semaphore init_sem; struct obd_connect_data conn_data; }; +struct gks_crypto_key { + char *key; + int len; +}; +struct gks_obd { + struct ptlrpc_service *gks_service; + struct crypto_tfm *gks_mac_tfm; + struct crypto_tfm *gks_key_tfm; + struct gks_crypto_key gks_key; +}; struct niobuf_local { __u64 offset; @@ -700,6 +711,7 @@ struct obd_device { struct lmv_obd lmv; struct cm_obd cm; struct conf_obd conf; + struct gks_obd gks; } u; /* fields used by LProcFS */ @@ -921,7 +933,7 @@ struct md_ops { struct ptlrpc_request **); int (*m_setattr)(struct obd_export *, struct mdc_op_data *, struct iattr *, void *, int , void *, int, - struct ptlrpc_request **); + void *, int, struct ptlrpc_request **); int (*m_sync)(struct obd_export *, struct lustre_id *, struct ptlrpc_request **); int (*m_readpage)(struct obd_export *, struct lustre_id *, diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 592eac5..d208c2b 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -102,6 +102,7 @@ struct lustre_profile { char *lp_profile; char *lp_lov; char *lp_lmv; + char *lp_gkc; }; struct lustre_profile *class_get_profile(char * prof); @@ -1349,7 +1350,7 @@ static inline int md_rename(struct obd_export *exp, struct mdc_op_data *data, static inline int md_setattr(struct obd_export *exp, struct mdc_op_data *data, struct iattr *iattr, void *ea, int ealen, - void *ea2, int ea2len, + void *ea2, int ea2len, void *ea3, int ea3len, struct ptlrpc_request **request) { int rc; @@ -1357,7 +1358,7 @@ static inline int md_setattr(struct obd_export *exp, struct mdc_op_data *data, EXP_CHECK_MD_OP(exp, setattr); MD_COUNTER_INCREMENT(exp->exp_obd, setattr); rc = MDP(exp->exp_obd, setattr)(exp, data, iattr, ea, ealen, - ea2, ea2len, request); + ea2, ea2len, ea3, ea3len, request); RETURN(rc); } diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 65a18d4..2c1eadd 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -67,6 +67,10 @@ #define LL_IOC_SETFACL _IOW ('f', 164, long) #define LL_IOC_FLUSH_CRED _IOW ('f', 170, long) +#define LL_IOC_KEY_TYPE _IOW ('f', 171, long) +#define LL_IOC_DISABLE_CRYPTO _IOW ('f', 172, long) +#define LL_IOC_ENABLE_CRYPTO _IOW ('f', 173, long) + #define O_LOV_DELAY_CREATE 0100000000 /* hopefully this does not conflict */ diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.10-fc3.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.10-fc3.patch index 2a4bc1f..0cdbd51 100644 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.10-fc3.patch +++ b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.10-fc3.patch @@ -942,7 +942,7 @@ Index: linux-2.6.10/fs/ext3/mballoc.c + * The only thing we can do is just take first + * found block(s) + */ -+ /*printk(KERN_ERR "EXT3-fs: and someone won our chunk\n");*/ ++ printk(KERN_ERR "EXT3-fs: and someone won our chunk\n"); + ac.ac_b_ex.fe_group = 0; + ac.ac_b_ex.fe_start = 0; + ac.ac_b_ex.fe_len = 0; diff --git a/lustre/kernel_patches/series/2.6-fc3-uml.series b/lustre/kernel_patches/series/2.6-fc3-uml.series index f32cf70..6abe6cc 100644 --- a/lustre/kernel_patches/series/2.6-fc3-uml.series +++ b/lustre/kernel_patches/series/2.6-fc3-uml.series @@ -5,7 +5,7 @@ kgdb-ga.patch lustre_version.patch vfs-dcache_locking-vanilla-2.6.10-fc3.patch vfs-dcache_lustre_invalid-vanilla-2.6.patch -vfs-intent_api-vanilla-2.6.10-fc3.patch +vfs-intent_api-vanilla-2.6.10-fc3.patch vfs-lookup_last-vanilla-2.6.10-fc3.patch vfs-raw_ops-vanilla-2.6.10-fc3.patch export-2.6-fc3.patch diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index f08b991..fc8519c 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -36,6 +36,7 @@ #include #include #include +#include /* @priority: if non-zero, move the selected to the list head * @nocreate: if non-zero, only search in existed connections @@ -197,6 +198,11 @@ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) rq_portal = MGMT_REQUEST_PORTAL; rp_portal = MGMT_REPLY_PORTAL; connect_op = MGMT_CONNECT; + } else if (!strcmp(name, LUSTRE_GKC_NAME)) { + rq_portal = GKS_REQUEST_PORTAL; + rp_portal = GKC_REPLY_PORTAL; + connect_op = GKS_CONNECT; + } else { CERROR("unknown client OBD type \"%s\", can't setup\n", name); diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c index 3633d87..4aaaa22 100644 --- a/lustre/ldlm/ldlm_resource.c +++ b/lustre/ldlm/ldlm_resource.c @@ -371,6 +371,7 @@ int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags) while (tmp != &(ns->ns_hash[i])) { struct ldlm_resource *res; res = list_entry(tmp, struct ldlm_resource, lr_hash); + spin_unlock(&ns->ns_hash_lock); ldlm_resource_getref(res); spin_unlock(&ns->ns_hash_lock); diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h index 0c457a3..8a9ac28 100644 --- a/lustre/liblustre/llite_lib.h +++ b/lustre/liblustre/llite_lib.h @@ -46,6 +46,7 @@ struct llu_sb_info { struct obd_uuid ll_sb_uuid; struct obd_export *ll_md_exp; struct obd_export *ll_dt_exp; + struct obd_export *ll_gt_exp; obd_id ll_rootino; int ll_flags; struct list_head ll_conn_chain; diff --git a/lustre/llite/Makefile.in b/lustre/llite/Makefile.in index 4b786a3..fe89a59 100644 --- a/lustre/llite/Makefile.in +++ b/lustre/llite/Makefile.in @@ -1,5 +1,6 @@ MODULES := llite -llite-objs := dcache.o dir.o file.o llite_close.o llite_gns.o llite_lib.o llite_nfs.o rw.o lproc_llite.o namei.o special.o symlink.o llite_mmap.o +llite-objs := dcache.o dir.o file.o llite_close.o llite_gns.o llite_lib.o llite_nfs.o +llite-objs += rw.o lproc_llite.o namei.o special.o symlink.o llite_mmap.o llite_gs.o ifeq ($(PATCHLEVEL),4) llite-objs += rw24.o super.o diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 0bb8b83..a40f558 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -31,7 +31,6 @@ #include #include #include - #include "llite_internal.h" /* should NOT be called with the dcache lock, see fs/dcache.c */ @@ -285,6 +284,14 @@ int ll_intent_alloc(struct lookup_intent *it) void ll_intent_free(struct lookup_intent *it) { if (it->d.fs_data) { + struct lustre_intent_data *lustre_data = + (struct lustre_intent_data *)it->d.fs_data; + if (lustre_data->it_key) { + OBD_FREE(lustre_data->it_key, + lustre_data->it_key_size); + lustre_data->it_key = NULL; + lustre_data->it_key_size = 0; + } OBD_SLAB_FREE(it->d.fs_data, ll_intent_slab, sizeof(struct lustre_intent_data)); it->d.fs_data = NULL; @@ -429,7 +436,11 @@ int ll_revalidate_it(struct dentry *de, int flags, struct nameidata *nd, do_lock: ll_frob_intent(&it, &lookup_it); LASSERT(it != NULL); - + + rc = ll_crypto_init_it_key(de->d_inode, it); + if (rc) + GOTO(out, rc); + rc = md_intent_lock(exp, &pid, (char *)de->d_name.name, de->d_name.len, NULL, 0, &cid, it, flags, &req, ll_mdc_blocking_ast); /* If req is NULL, then md_intent_lock() only tried to do a lock match; @@ -531,7 +542,9 @@ do_lookup: if (ll_intent_alloc(it)) LBUG(); } - + rc = ll_crypto_init_it_key(de->d_inode, it); + if (rc) + GOTO(out, rc); rc = md_intent_lock(exp, &pid, (char *)de->d_name.name, de->d_name.len, NULL, 0, NULL, it, 0, &req, ll_mdc_blocking_ast); if (rc >= 0) { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 55e6e79..2d144d7 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -526,7 +526,7 @@ static int ll_ioctl_setfacl(struct inode *inode, rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, &op_data, &attr, (void*) XATTR_NAME_LUSTRE_ACL, sizeof(XATTR_NAME_LUSTRE_ACL), - (void*) cmd, ioc->cmd_len, &req); + (void*) cmd, ioc->cmd_len, NULL, 0, &req); if (rc) { CERROR("md_setattr fails: rc = %d\n", rc); GOTO(out, rc); @@ -611,6 +611,29 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, obd_ioctl_freedata(buf, len); return rc; } + case LL_IOC_KEY_TYPE: { + char *buf = NULL; + char *type; + int typelen, rc, len = 0; + + rc = obd_ioctl_getdata(&buf, &len, (void *)arg); + if (rc) + RETURN(rc); + data = (void *)buf; + + type = data->ioc_inlbuf1; + typelen = data->ioc_inllen1; + + if (typelen < 1) { + CDEBUG(D_INFO, "LL_IOC_KEY_TYPE missing filename\n"); + GOTO(out_free, rc = -EINVAL); + } + ll_set_sb_gksinfo(inode->i_sb, type); + EXIT; + out_free: + obd_ioctl_freedata(buf, len); + RETURN(rc); + } case LL_IOC_MDC_MKDIRSTRIPE: RETURN(ll_mkdir_stripe(inode, arg)); case LL_IOC_LOV_SETSTRIPE: { @@ -637,7 +660,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, ll_prepare_mdc_data(op_data, inode, NULL, NULL, 0, 0); rc = md_setattr(sbi->ll_md_exp, op_data, &attr, &lum, - sizeof(lum), NULL, 0, &request); + sizeof(lum), NULL, 0, NULL, 0, &request); OBD_FREE(op_data, sizeof(*op_data)); ptlrpc_req_finished(request); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 2394c4a..608606b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -114,7 +114,6 @@ int ll_md_och_close(struct obd_export *md_exp, struct inode *inode, obdo->o_fid = id_fid(&ll_i2info(inode)->lli_id); obdo->o_mds = id_group(&ll_i2info(inode)->lli_id); - obdo->o_valid |= OBD_MD_FLEPOCH; obdo->o_easize = ll_i2info(inode)->lli_io_epoch; @@ -429,7 +428,6 @@ int ll_file_open(struct inode *inode, struct file *file) oit.it_flags |= 2; it = file->f_it; - /* * sometimes LUSTRE_IT(it) may not be allocated like opening file by * dentry_open() from GNS stuff. @@ -465,6 +463,10 @@ int ll_file_open(struct inode *inode, struct file *file) och_usecount = &lli->lli_open_fd_read_count; } + rc = ll_crypto_decrypt_key(inode, it); + if (rc) + GOTO(out, rc); + down(&lli->lli_och_sem); if (*och_p) { /* Open handle is present */ if (it_disposition(it, DISP_LOOKUP_POS) && /* Positive lookup */ @@ -1514,6 +1516,31 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, putname(filename); return rc; } + case LL_IOC_KEY_TYPE: { + struct obd_ioctl_data *data; + char *buf = NULL; + char *type; + int typelen, rc, len = 0; + + rc = obd_ioctl_getdata(&buf, &len, (void *)arg); + if (rc) + RETURN(rc); + data = (void *)buf; + + type = data->ioc_inlbuf1; + typelen = data->ioc_inllen1; + + if (typelen < 1) { + CDEBUG(D_INFO, "LL_IOC_KEY_TYPE missing filename\n"); + GOTO(out, rc = -EINVAL); + } + ll_set_sb_gksinfo(inode->i_sb, type); + EXIT; + out: + obd_ioctl_freedata(buf, len); + return rc; + } + case LL_IOC_LOV_GETSTRIPE: RETURN(ll_lov_getstripe(inode, arg)); case EXT3_IOC_GETFLAGS: @@ -1761,6 +1788,10 @@ int ll_inode_revalidate_it(struct dentry *dentry) rc = ll_intent_alloc(&oit); if (rc) RETURN(-ENOMEM); + + rc = ll_crypto_init_it_key(inode, &oit); + if (rc) + GOTO(out, rc); rc = md_intent_lock(sbi->ll_md_exp, &id, NULL, 0, NULL, 0, &id, &oit, 0, &req, ll_mdc_blocking_ast); @@ -1834,7 +1865,8 @@ int ll_setxattr_internal(struct inode *inode, const char *name, struct ptlrpc_request *request = NULL; struct mdc_op_data op_data; struct iattr attr; - int rc = 0; + void *key = NULL; + int rc = 0, key_size = 0; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino); @@ -1847,15 +1879,24 @@ int ll_setxattr_internal(struct inode *inode, const char *name, attr.ia_valid |= valid; attr.ia_attr_flags = flags; + if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) { + rc = ll_crypto_get_mac(inode, NULL, (void *)value, size, + &key, &key_size); + } + ll_prepare_mdc_data(&op_data, inode, NULL, NULL, 0, 0); rc = md_setattr(sbi->ll_md_exp, &op_data, &attr, - (void*) name, strnlen(name, XATTR_NAME_MAX) + 1, - (void*) value, size, &request); - if (rc) + (void*) name, strnlen(name, XATTR_NAME_MAX) + 1, + (void*) value, size, key, key_size, &request); + + if (key && key_size) + OBD_FREE(key, key_size); + if (rc) { + CERROR("md_setattr fails: rc = %d\n", rc); GOTO(out, rc); - - out: + } +out: ptlrpc_req_finished(request); RETURN(rc); } @@ -1909,7 +1950,6 @@ int ll_removexattr(struct dentry *dentry, const char *name) ATTR_EA_RM); } -static int ll_getxattr_internal(struct inode *inode, const char *name, void *value, size_t size, __u64 valid) { diff --git a/lustre/llite/llite_close.c b/lustre/llite/llite_close.c index 7588c60..31219db 100644 --- a/lustre/llite/llite_close.c +++ b/lustre/llite/llite_close.c @@ -27,6 +27,7 @@ #include #include +#include #include "llite_internal.h" /* record that a write is in flight */ diff --git a/lustre/llite/llite_gs.c b/lustre/llite/llite_gs.c new file mode 100644 index 0000000..74cf8dd --- /dev/null +++ b/lustre/llite/llite_gs.c @@ -0,0 +1,791 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2004, 2005 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DEBUG_SUBSYSTEM S_LLITE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "llite_internal.h" + +int ll_gs_intent_init(struct lookup_intent *it) +{ + struct lustre_intent_data *lustre_data; + + LASSERT(it->d.fs_data != NULL); + lustre_data = (struct lustre_intent_data *)it->d.fs_data; + /*set lustre key size when there is gss server + *or other configuration*/ + lustre_data->it_key = NULL; + lustre_data->it_key_size = 0; + RETURN(0); +} + +static int ll_get_acl_key(struct inode *inode, struct posix_acl **acl, + struct lustre_key **lkey) +{ + struct lookup_intent it = { .it_op = IT_GETATTR }; + struct dentry de = { .d_inode = inode }; + struct ll_sb_info *sbi; + struct lustre_id id; + struct ptlrpc_request *req = NULL; + struct ll_inode_info *lli = ll_i2info(inode); + int rc = 0; + ENTRY; + + if (lli->lli_posix_acl && lli->lli_key_info) { + /*If they are in the local cache, just fetch them*/ + spin_lock(&lli->lli_lock); + *acl = posix_acl_dup(lli->lli_posix_acl); + *lkey = lustre_key_get(lli->lli_key_info); + spin_unlock(&lli->lli_lock); + RETURN(rc); + } + sbi = ll_i2sbi(inode); + ll_inode2id(&id, inode); + + if (ll_intent_alloc(&it)) + RETURN(-EACCES); + + rc = md_intent_lock(sbi->ll_md_exp, &id, NULL, 0, NULL, 0, &id, + &it, 0, &req, ll_mdc_blocking_ast); + if (rc < 0) { + ll_intent_free(&it); + GOTO(out, rc); + } + + rc = revalidate_it_finish(req, 1, &it, &de); + if (rc) { + ll_intent_release(&it); + GOTO(out, rc); + } + + ll_lookup_finish_locks(&it, &de); + ll_intent_free(&it); + + spin_lock(&lli->lli_lock); + *acl = posix_acl_dup(lli->lli_posix_acl); + *lkey = lustre_key_get(lli->lli_key_info); + spin_unlock(&lli->lli_lock); +out: + if (req) + ptlrpc_req_finished(req); + RETURN(rc); +} + +static int ll_init_key_perm(struct key_perm *kperm, struct posix_acl *acl, + __u32 uid, __u32 gid, int mode) +{ + if (acl) { + kperm->kp_acl_count = acl->a_count; + memcpy(kperm->kp_acls, acl->a_entries, + acl->a_count * sizeof(struct posix_acl_entry)); + } + kperm->kp_mode = mode; + kperm->kp_uid = uid; + kperm->kp_gid = gid; + RETURN(0); +} + +static int ll_init_key_context(struct key_context *pkc, __u32 uid, + __u32 gid, struct crypto_key *ck, + struct posix_acl *acl, int mode, + int command, int valid) +{ + struct key_perm *kperm; + ENTRY; + + pkc->kc_command = command; + pkc->kc_valid = valid; + + if (ck) + memcpy(&pkc->kc_ck, ck, sizeof(*ck)); + + kperm = &pkc->kc_perm; + + ll_init_key_perm(kperm, acl, uid, gid, mode); + RETURN(0); +} +static int ll_get_default_acl(struct inode *inode, struct posix_acl **acl, + mode_t mode) +{ + int rc = 0, buf_size, ea_size; + char *buf = NULL; + ENTRY; + + if (!S_ISDIR(inode->i_mode)) + RETURN(0); + + buf_size = xattr_acl_size(LL_ACL_MAX_ENTRIES); + OBD_ALLOC(buf, buf_size); + if (!buf) + RETURN(-ENOMEM); + + ea_size = ll_getxattr_internal(inode, XATTR_NAME_ACL_DEFAULT, + buf, buf_size, OBD_MD_FLXATTR); + if (ea_size <= 0) { + if (ea_size < 0 && ea_size != -ENODATA) + CERROR("get default acl of ino %lu error rc %d \n", + inode->i_ino, ea_size); + GOTO(out, rc = 0); + } + *acl = posix_acl_from_xattr(buf, ea_size); + if (IS_ERR(*acl)) { + rc = PTR_ERR(*acl); + CERROR("convert xattr to acl failed: %d\n", rc); + GOTO(out, rc); + } else if (*acl) { + rc = posix_acl_valid(*acl); + if (rc) { + CERROR("acl valid error: %d\n", rc); + posix_acl_release(*acl); + GOTO(out, rc); + } + } + + rc = posix_acl_create_masq(*acl, &mode); +out: + if (buf) + OBD_FREE(buf, buf_size); + RETURN(rc); +} + +int ll_gks_create_key(struct inode *dir, mode_t mode, void **key, + int* key_size) +{ + struct obd_export *gs_exp = ll_i2gsexp(dir); + struct key_context *kcontext = NULL; + struct key_parms kparms; + struct posix_acl *default_acl = NULL; + int rc = 0; + ENTRY; + + OBD_ALLOC(kcontext, sizeof(struct key_context)); + if (!kcontext) + GOTO(out, rc = -ENOMEM); + + rc = ll_get_default_acl(dir, &default_acl, mode); + if (rc) + GOTO(out, rc); + + ll_init_key_context(kcontext, current->fsuid, current->fsgid, + NULL, default_acl, mode, GKS_GET_KEY, 0); + + kparms.context = kcontext; + kparms.context_size = sizeof(struct key_context); + kparms.perm = NULL; + + *key_size = sizeof(struct crypto_key); + OBD_ALLOC(*key, *key_size); + if (!*key) + GOTO(out, rc = -ENOMEM); + + /*GET an encrypt key from GS server*/ + rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms, + key_size, *key); + if (rc) { + CERROR("get key error rc %d \n", rc); + GOTO(out, rc); + } + CDEBUG(D_INFO, "Get enkey %s MAC %s from exp %p \n", + (char*)((struct crypto_key *)(*key))->ck_key, + (char*)((struct crypto_key *)(*key))->ck_mac, + gs_exp); +out: + if (kcontext) + OBD_FREE(kcontext, sizeof(struct key_context)); + if (default_acl) + posix_acl_release(default_acl); + RETURN(rc); + +} + +int ll_gks_init_it(struct inode *parent, struct lookup_intent *it) +{ + struct obd_export *gs_exp = ll_i2gsexp(parent); + struct lustre_intent_data *lustre_data; + mode_t mode = (it->it_create_mode | S_IFREG) & (~current->fs->umask); + void *key = NULL; + int key_size = 0, rc = 0; + ENTRY; + + if (!gs_exp || !it) + RETURN(rc); + + ll_gs_intent_init(it); + if (!(it->it_op & IT_CREAT)) + RETURN(rc); + + LASSERT(it->d.fs_data != NULL); + lustre_data = (struct lustre_intent_data *)it->d.fs_data; + + if (lustre_data->it_key) { + LASSERT(lustre_data->it_key_size == + sizeof(struct crypto_key)); + OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key)); + } + + rc = ll_gks_create_key(parent, mode, &key, &key_size); + if (rc) + GOTO(out, rc); + + lustre_data->it_key = key; + lustre_data->it_key_size = key_size; +out: + if (rc) { + if (key && key_size) + OBD_FREE(key, key_size); + } + RETURN(rc); +} + +int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it) +{ + struct obd_export *gs_exp = ll_i2gsexp(inode); + struct ll_inode_info *lli = ll_i2info(inode); + struct key_context *kcontext = NULL; + struct key_perm *kperm = NULL; + struct key_parms kparms; + struct lustre_key *lkey = NULL; + struct crypto_key *ckey = NULL; + struct posix_acl *acl = NULL; + __u32 flags = 0; + int rc = 0, ck_size = 0, kcontext_size = 0, acl_count; + + ENTRY; + + if (!gs_exp) + RETURN(rc); + + rc = ll_get_acl_key(inode, &acl, &lkey); + if (rc) + GOTO(out, rc); + if (!lkey || IS_DECRYPTED(lkey->lk_flags)) + GOTO(out, rc = 0); + + acl_count = acl ? acl->a_count : 0; + kcontext_size = crypto_kcontext_size(acl_count); + OBD_ALLOC(kcontext, kcontext_size); + if (!kcontext) + GOTO(out, rc = -ENOMEM); + + flags = mds_pack_open_flags(it->it_flags); + + spin_lock(&lli->lli_lock); + ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, + acl, inode->i_mode, GKS_DECRYPT_KEY, flags); + + spin_unlock(&lli->lli_lock); + + OBD_ALLOC(kperm, sizeof(struct key_perm)); + ll_init_key_perm(kperm, NULL, current->uid, current->gid, 0); + + kparms.context = kcontext; + kparms.context_size = kcontext_size; + kparms.perm = kperm; + kparms.perm_size = sizeof(struct key_perm); + + ck_size = sizeof(*ckey); + OBD_ALLOC(ckey, ck_size); + if (!ckey) + GOTO(out, rc = -ENOMEM); + + /*GET an encrypt key from GS server*/ + rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms, + &ck_size, ckey); + if (rc) { + CERROR("decrypt key error rc %d \n", rc); + GOTO(out, rc); + } + CDEBUG(D_INFO, "decrypt key %s MAC %s from exp %p \n", + ckey->ck_mac, ckey->ck_mac, gs_exp); + + /*copy the decrypt key from kcontext to the lustre key*/ + + spin_lock(&lli->lli_lock); + memcpy(&lkey->lk_ck, ckey, sizeof(*ckey)); + SET_DECRYPTED(lkey->lk_flags); + spin_unlock(&lli->lli_lock); +out: + if (acl) + posix_acl_release(acl); + if (lkey) + lustre_key_release(lkey); + if (kperm) + OBD_FREE(kperm, sizeof(struct key_perm)); + if (kcontext) + OBD_FREE(kcontext, kcontext_size); + if (ckey) + OBD_FREE(ckey, ck_size); + RETURN(rc); +} + +int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value, + int size, void **key, int *key_size) +{ + struct ll_inode_info *lli = ll_i2info(inode); + struct obd_export *gs_exp = ll_i2gsexp(inode); + struct key_context *kcontext = NULL; + struct key_perm *kperm = NULL; + struct key_parms kparms; + struct lustre_key *lkey = NULL; + struct posix_acl *acl = NULL, *new_acl = NULL; + int rc = 0, kperm_size = 0, kcontext_size = 0; + mode_t mac_mode; + int acl_count = 0; + + ENTRY; + + if (!gs_exp) + RETURN(rc); + + rc = ll_get_acl_key(inode, &acl, &lkey); + if (rc) + GOTO(out, rc); + if (!lkey) + RETURN(rc); + + acl_count = acl ? acl->a_count : 0; + kcontext_size = crypto_kcontext_size(acl_count); + OBD_ALLOC(kcontext, kcontext_size); + if (!kcontext) + GOTO(out, rc = -ENOMEM); + spin_lock(&lli->lli_lock); + ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, + acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid); + spin_unlock(&lli->lli_lock); + if (value) { + new_acl = posix_acl_from_xattr(value, size); + if (IS_ERR(new_acl)) { + rc = PTR_ERR(new_acl); + CERROR("convert from xattr to acl error: %d",rc); + new_acl = NULL; + GOTO(out, rc); + } else if (new_acl) { + rc = posix_acl_valid(new_acl); + if (rc) { + CERROR("acl valid error: %d", rc); + GOTO(out, rc); + } + } + } + acl_count = acl ? acl->a_count : 0; + kperm_size = crypto_kperm_size(acl_count); + OBD_ALLOC(kperm, kperm_size); + if (iattr->ia_valid & ATTR_MODE) + mac_mode = iattr->ia_mode; + else + mac_mode = inode->i_mode; + ll_init_key_perm(kperm, new_acl, iattr->ia_uid, iattr->ia_gid, + mac_mode); + kparms.context = kcontext; + kparms.context_size = kcontext_size; + kparms.perm = kperm; + kparms.perm_size = kperm_size; + + *key_size = sizeof(struct crypto_key); + OBD_ALLOC(*key, *key_size); + if (!*key) + GOTO(out, rc = -ENOMEM); + + /*GET an encrypt key from GS server*/ + rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms, + key_size, *key); + if (rc) { + CERROR("decrypt key error rc %d \n", rc); + GOTO(out, rc); + } + /*copy the decrypt key from kcontext to the lustre key*/ + spin_lock(&lli->lli_lock); + memcpy(&lkey->lk_ck, *key, *key_size); + iattr->ia_valid |= ATTR_MAC; + spin_unlock(&lli->lli_lock); +out: + if (acl) + posix_acl_release(acl); + if (new_acl) + posix_acl_release(new_acl); + if (lkey) + lustre_key_release(lkey); + if (kperm) + OBD_FREE(kperm, kperm_size); + if (kcontext) + OBD_FREE(kcontext, kcontext_size); + RETURN(rc); +} + +/*key function for calculate the key for countermode method*/ +static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count, + int flags) +{ + struct inode *inode = page->mapping->host; + struct ll_inode_info *lli = ll_i2info(inode); + struct lustre_key *lkey = ll_i2info(inode)->lli_key_info; + unsigned char *ptr; + char *key_ptr; + int index = page->index; + __u64 data_key = 0; + int i; + ENTRY; + + if (!lkey) + RETURN(0); + if (!IS_DECRYPTED(lkey->lk_flags)) + RETURN(-EFAULT); + if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags)) + RETURN(-EFAULT); + if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags)) + RETURN(-EFAULT); + + /*FIXME: tmp calculate method, should calculate + the key according to KEY_TYPE*/ + + spin_lock(&lli->lli_lock); + key_ptr = &lkey->lk_ck.ck_key[0]; + for (i=0; i < KEY_SIZE; i++) + data_key += *key_ptr++; + spin_unlock(&lli->lli_lock); + data_key += index; + + CDEBUG(D_INFO, "data_key is "LPU64" \n", data_key); + /*encrypt the data*/ + ptr = (char *)kmap(page); + ptr += offset; + CDEBUG(D_INFO, "ptr is %s \n", ptr); + for (i = 0; i < count; i++) + *ptr++ ^= data_key; + CDEBUG(D_INFO, "encrypted ptr is %s \n", ptr); + kunmap(page); + + RETURN(0); +} + +int ll_gs_init_inode_key(struct inode *inode, void *mkey) +{ + struct ll_inode_info *lli = ll_i2info(inode); + struct crypto_key *key = (struct crypto_key*)mkey; + struct lustre_key *lkey = NULL; + ENTRY; + + if (!key) + RETURN(0); + + if (lli->lli_key_info == NULL) { + OBD_ALLOC(lkey, sizeof(struct lustre_key)); + if (!lkey) + RETURN(-ENOMEM); + memcpy(&lkey->lk_ck, key, sizeof(*key)); + atomic_set(&lkey->lk_refcount, 1); + SET_UNDECRYPTED(lkey->lk_flags); + ENABLE_ENCRYPT(lkey->lk_flags); + ENABLE_DECRYPT(lkey->lk_flags); + spin_lock(&lli->lli_lock); + lli->lli_key_info = lkey; + spin_unlock(&lli->lli_lock); + } else { + lkey = lustre_key_get(lli->lli_key_info); + if (!IS_DECRYPTED(lkey->lk_flags)) { + if (memcmp(&lkey->lk_ck, key, sizeof(*key))) { + CWARN("already have key_info %p in ino %ld \n", + lli->lli_key_info, inode->i_ino); + } + } else { + spin_lock(&lli->lli_lock); + SET_UNDECRYPTED(lkey->lk_flags); + memcpy(&lkey->lk_ck, key, sizeof(*key)); + spin_unlock(&lli->lli_lock); + } + lustre_key_release(lkey); + } + CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", + lli->lli_key_info->lk_ck.ck_mac, + lli->lli_key_info->lk_ck.ck_key, + inode->i_ino); + RETURN(0); +} + +static int ll_gs_destroy_key(struct inode *inode) +{ + struct ll_inode_info *lli = ll_i2info(inode); + + spin_lock(&lli->lli_lock); + if (lli->lli_key_info) { + LASSERTF(atomic_read(&lli->lli_key_info->lk_refcount) == 1, + "lk_refcount %d != 1 when destory\n", + atomic_read(&lli->lli_key_info->lk_refcount)); + lustre_key_release(lli->lli_key_info); + lli->lli_key_info = NULL; + } + spin_unlock(&lli->lli_lock); + RETURN(0); +} + +struct crypto_helper_ops ll_cgs_ops = { + .init_it_key = ll_gks_init_it, + .create_key = ll_gks_create_key, + .init_inode_key = ll_gs_init_inode_key, + .get_mac = ll_gks_get_mac, + .decrypt_key = ll_gks_decrypt_key, + .destroy_key = ll_gs_destroy_key, +}; + +int ll_mks_create_key(struct inode *inode, struct lookup_intent *it) +{ + struct lustre_intent_data *lustre_data; + struct crypto_key *crypto_key; + int rc = 0; + ENTRY; + + LASSERT(it->d.fs_data != NULL); + lustre_data = (struct lustre_intent_data *)it->d.fs_data; + + if (lustre_data->it_key) { + OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key)); + } + OBD_ALLOC(crypto_key, sizeof(struct crypto_key)); + + lustre_data->it_key = crypto_key; + lustre_data->it_key_size = sizeof(struct crypto_key); + RETURN(rc); +} + +int ll_mks_init_it(struct inode *parent, struct lookup_intent *it) +{ + struct obd_export *gs_exp = ll_i2gsexp(parent); + int rc = 0; + ENTRY; + + if (!gs_exp || !it) + RETURN(0); + + ll_gs_intent_init(it); + if (it->it_op & IT_CREAT) { + ll_mks_create_key(parent, it); + } + RETURN(rc); +} + +int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it) +{ + struct ll_inode_info *lli = ll_i2info(inode); + struct obd_export *gs_exp = ll_i2gsexp(inode); + struct lustre_key *lkey = NULL; + struct posix_acl *acl = NULL; + int rc = 0; + + ENTRY; + + if (!gs_exp) + RETURN(rc); + + rc = ll_get_acl_key(inode, &acl, &lkey); + if (rc || !lkey) + RETURN(rc); + spin_lock(&lli->lli_lock); + SET_DECRYPTED(lkey->lk_flags); + spin_unlock(&lli->lli_lock); + RETURN(rc); +} +struct crypto_helper_ops ll_cmd_ops = { + .init_it_key = ll_mks_init_it, + .init_inode_key = ll_gs_init_inode_key, + .decrypt_key = ll_mks_decrypt_key, + .destroy_key = ll_gs_destroy_key, +}; + + +static int ll_register_cops(struct ll_crypto_info *llci, char *type, + struct crypto_helper_ops *cops) +{ + struct list_head *list = &llci->ll_cops_list; + struct crypto_ops_item *opi = NULL, *tmp; + char *opi_name = NULL; + int rc = 0; + ENTRY; + + list_for_each_entry(tmp, list, clist) { + if (!strcmp(type, tmp->ctype)) { + CWARN("%s is already registered\n", type); + rc = -EEXIST; + GOTO(exit, rc); + } + } + + OBD_ALLOC(opi, sizeof(*opi)); + + OBD_ALLOC(opi_name, strlen(type) + 1); + + LASSERT(opi && opi_name); + + memcpy(opi_name, type, strlen(type)); + + opi->ctype = opi_name; + opi->cops = cops; + + list_add_tail(&opi->clist, list); +exit: + RETURN(rc); +} + +static int ll_init_sb_crypto(struct super_block *sb) +{ + struct ll_crypto_info *llci = NULL; + int rc = 0; + ENTRY; + + OBD_ALLOC(llci, sizeof(*llci)); + + if (!llci) + RETURN(-ENOMEM); + + INIT_LIST_HEAD(&llci->ll_cops_list); + + ll_register_cops(llci, "gks", &ll_cgs_ops); + ll_register_cops(llci, "mks", &ll_cmd_ops); + + ll_s2sbi(sb)->ll_crypto_info = llci; + + RETURN(rc); +} + +static int ll_unregister_cops(struct ll_crypto_info *llci) +{ + struct list_head *list = &llci->ll_cops_list; + struct crypto_ops_item *tmp, *item; + + list_for_each_entry_safe(item, tmp, list, clist) { + list_del_init(&item->clist); + OBD_FREE(item->ctype, strlen(item->ctype) + 1); + OBD_FREE(item, sizeof(*item)); + } + RETURN(0); +} + +int lustre_destroy_crypto(struct super_block *sb) +{ + struct ll_crypto_info *llci = ll_s2crpi(sb); + ENTRY; + + if (!llci) + RETURN(0); + + if (llci->ll_gt_exp) + obd_disconnect(llci->ll_gt_exp, 0); + + ll_unregister_cops(llci); + OBD_FREE(llci, sizeof(*llci)); + RETURN(0); +} + +int lustre_init_crypto(struct super_block *sb, char *gkc, + struct obd_connect_data *data, + int async) +{ + struct obd_device *obd = NULL; + struct ll_sb_info *sbi = ll_s2sbi(sb); + struct lustre_handle gt_conn; + int rc = 0; + ENTRY; + + rc = ll_init_sb_crypto(sb); + if (rc) + RETURN(rc); + + if (!gkc || !strcmp(gkc, "null")) { + CDEBUG(D_INFO, "No gks Server\n"); + RETURN(rc); + } + + obd = class_name2obd(gkc); + if (!obd) { + CERROR("GSC %s: not setup or attached\n", gkc); + GOTO(out, rc = -EINVAL); + } + + obd_set_info(obd->obd_self_export, strlen("async"), "async", + sizeof(async), &async); + + rc = obd_connect(>_conn, obd, &sbi->ll_sb_uuid, data, + OBD_OPT_REAL_CLIENT); + if (rc) { + CERROR("cannot connect to %s: rc = %d\n", gkc, rc); + GOTO(out, rc); + } + ll_s2crpi(sb)->ll_gt_exp = class_conn2export(>_conn); +out: + if (rc) + lustre_destroy_crypto(sb); + RETURN(rc); +} +struct crypto_helper_ops * +ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type) +{ + struct list_head *list = &llc_info->ll_cops_list; + struct crypto_ops_item *tmp; + ENTRY; + + list_for_each_entry(tmp, list, clist) { + if (!strcmp(type, tmp->ctype)) { + EXIT; + return (tmp->cops); + } + } + CERROR("can not find crypto api %s \n", type); + RETURN(NULL); +} + +int ll_set_sb_gksinfo(struct super_block *sb, char *type) +{ + struct ll_crypto_info *llci = ll_s2crpi(sb); + struct obd_export *md_exp = ll_s2mdexp(sb); + struct obd_export *dt_exp = ll_s2dtexp(sb); + struct crypto_helper_ops *ops; + int rc = 0; + ENTRY; + + /*try to find the helper ops according to the type*/ + ops = ll_gks_find_ops(llci, type); + if (!ops) { + CERROR("can not find the crypto ops by type %s \n", type); + RETURN(-EINVAL); + } + llci->ll_cops = ops; + /*set crypto type */ + rc = obd_set_info(md_exp, strlen("crypto_type"), "crypto_type", + strlen(type), type); + + /*set crypt call back func*/ + + rc = obd_set_info(dt_exp, strlen("crypto_cb"), "crypto_cb", + sizeof(crypt_cb_t), &ll_crypt_cb); + + RETURN(rc); +} + diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index bfe6e11..d0bca7a 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -108,6 +108,7 @@ struct ll_sb_info { /* mount object entry name */ char ll_gns_oname[PATH_MAX]; + void *ll_crypto_info; }; struct ll_gns_ctl { @@ -257,9 +258,10 @@ void ll_removepage(struct page *page); int ll_readpage(struct file *file, struct page *page); struct ll_async_page *llap_from_cookie(void *cookie); struct ll_async_page *llap_from_page(struct page *page, unsigned origin); -struct ll_async_page *llap_cast_private(struct page *page); void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras); +struct lpage_data *lpd_cast_private(struct page *page); + void ll_ra_accounting(struct page *page, struct address_space *mapping); void ll_truncate(struct inode *inode); @@ -275,6 +277,8 @@ int ll_getxattr(struct dentry *, const char *, void *, size_t); int ll_listxattr(struct dentry *, char *, size_t); int ll_removexattr(struct dentry *, const char *); extern int ll_inode_permission(struct inode *, int, struct nameidata *); +int ll_get_acl(struct inode *, struct posix_acl **acl, + struct ptlrpc_request **req); int ll_refresh_lsm(struct inode *inode, struct lov_stripe_md *lsm); int ll_extent_lock(struct ll_file_data *, struct inode *, struct lov_stripe_md *, int mode, ldlm_policy_data_t *, @@ -295,6 +299,8 @@ int ll_md_och_close(struct obd_export *md_exp, struct inode *inode, void ll_och_fill(struct inode *inode, struct lookup_intent *it, struct obd_client_handle *och); +int ll_getxattr_internal(struct inode *inode, const char *name, + void *value, size_t size, __u64 valid); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat); #endif @@ -334,8 +340,8 @@ extern struct super_operations lustre_super_operations; char *ll_read_opt(const char *opt, char *data); int ll_set_opt(const char *opt, char *data, int fl); -void ll_options(char *options, char **ost, char **mds, char **mds_sec, - char **oss_sec, int *async, int *flags); +void ll_options(char *options, char **ost, char **mds, char **gss, + char **mds_sec, char **oss_sec, int *async, int *flags); void ll_lli_init(struct ll_inode_info *lli); int ll_fill_super(struct super_block *sb, void *data, int silent); int lustre_fill_super(struct super_block *sb, void *data, int silent); @@ -486,7 +492,6 @@ static inline struct obd_export *ll_i2mdexp(struct inode *inode) { return ll_s2mdexp(inode->i_sb); } - static inline int ll_mds_max_easize(struct super_block *sb) { return sbi2md(ll_s2sbi(sb))->cl_max_mds_easize; @@ -497,6 +502,7 @@ static inline __u64 ll_file_maxbytes(struct inode *inode) return ll_i2info(inode)->lli_maxbytes; } + static inline void ll_inode2id(struct lustre_id *id, struct inode *inode) { @@ -530,8 +536,135 @@ ll_prepare_mdc_data(struct mdc_op_data *data, struct inode *i1, data->mod_time = LTIME_S(CURRENT_TIME); } -/* pass this flag to ll_md_real_close() to send close rpc right away */ -#define FMODE_SYNC 00000010 +struct crypto_helper_ops { + int (*init_it_key)(struct inode *inode, struct lookup_intent *it); + int (*create_key)(struct inode *dir, mode_t mode, void **key, + int* key_size); + int (*get_mac)(struct inode *inode, struct iattr *iattr, void*value, + int size, void **key, int* key_size); + int (*decrypt_key)(struct inode *inode, struct lookup_intent *it); + int (*init_inode_key)(struct inode *inode, void *md_key); + int (*destroy_key)(struct inode *inode); +}; + +/*llite crypto ops for crypto api*/ +struct ll_crypto_info { + struct obd_export *ll_gt_exp; + struct list_head ll_cops_list; + struct crypto_helper_ops *ll_cops; + int ll_c_flags; +}; +#define ll_page2key(page) ((ll_i2info(page->mapping->host))->lli_key_info) +static inline struct ll_crypto_info* ll_s2crpi(struct super_block *sb) +{ + return (struct ll_crypto_info*)ll_s2sbi(sb)->ll_crypto_info; +} +static inline struct ll_crypto_info* ll_i2crpi(struct inode *inode) +{ + return (struct ll_crypto_info*)ll_i2sbi(inode)->ll_crypto_info; +} + +static inline struct crypto_helper_ops* ll_i2crpops(struct inode *inode) +{ + return ll_i2crpi(inode)->ll_cops; +} +static inline struct crypto_helper_ops* ll_s2crpops(struct super_block *sb) +{ + return ll_s2crpi(sb)->ll_cops; +} +static inline struct obd_export *ll_s2gsexp(struct super_block *sb) +{ + struct ll_crypto_info *llci = ll_s2crpi(sb); + if (llci) + return llci->ll_gt_exp; + return NULL; +} +static inline struct obd_export *ll_i2gsexp(struct inode *inode) +{ + return ll_s2gsexp(inode->i_sb); +} + +static inline +int ll_crypto_init_it_key(struct inode *inode, struct lookup_intent *it) +{ + struct ll_crypto_info *lci = ll_i2crpi(inode); + if (lci) { + struct crypto_helper_ops *ops = lci->ll_cops;; + if (ops && ops->init_it_key) + return ops->init_it_key(inode, it); + } + return 0; +} + +static inline +int ll_crypto_create_key(struct inode *inode, mode_t mode, void **key, + int* key_size) +{ + struct ll_crypto_info *lci = ll_i2crpi(inode); + if (lci) { + struct crypto_helper_ops *ops = lci->ll_cops;; + if (ops && ops->create_key) + return ops->create_key(inode, mode, key, key_size); + } + return 0; +} + +static inline +int ll_crypto_get_mac(struct inode *inode, struct iattr *attr, void *acl, + int acl_size, void **mac, int *mac_size) +{ + struct ll_crypto_info *lci = ll_i2crpi(inode); + if (lci) { + struct crypto_helper_ops *ops = lci->ll_cops; + if (ops && ops->get_mac) + return ops->get_mac(inode, attr, acl, acl_size, + mac, mac_size); + } + return 0; +} + +static inline +int ll_crypto_decrypt_key(struct inode *inode, struct lookup_intent *it) +{ + struct ll_crypto_info *lci = ll_i2crpi(inode); + if (lci) { + struct crypto_helper_ops *ops = lci->ll_cops; + if (ops && ops->decrypt_key) + return ops->decrypt_key(inode, it); + } + return 0; +} + +static inline +int ll_crypto_init_inode_key(struct inode *inode, void *md_key) +{ + struct ll_crypto_info *lci = ll_i2crpi(inode); + if (lci) { + struct crypto_helper_ops *ops = lci->ll_cops; + if (ops && ops->init_inode_key) + return ops->init_inode_key(inode, md_key); + } + return 0; +} + +static inline +int ll_crypto_destroy_inode_key(struct inode *inode) +{ + struct ll_crypto_info *lci = ll_i2crpi(inode); + if (lci) { + struct crypto_helper_ops *ops = lci->ll_cops; + if (ops && ops->destroy_key) + return ops->destroy_key(inode); + } + return 0; +} + +int lustre_init_crypto(struct super_block *sb, char *gkc, + struct obd_connect_data *data, int async); +int lustre_destroy_crypto(struct super_block *sb); +int ll_set_sb_gksinfo(struct super_block *sb, char *type); +/* pass this flag to ll_md_real_close() to send close rpc right away */ +#define FMODE_SYNC 00000010 #endif /* LLITE_INTERNAL_H */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index cf515f4..ce919b7 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "llite_internal.h" @@ -128,63 +129,40 @@ int lustre_init_dt_desc(struct ll_sb_info *sbi) RETURN(rc); } -extern struct dentry_operations ll_d_ops; - -int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, - int async, char *mds_security, char *oss_security, - __u32 *nllu, int pag, __u64 *remote) +static int lustre_connect_mds(struct super_block *sb, char *lmv, + struct obd_connect_data *data, + char *mds_security, int async, int pag) { struct ll_sb_info *sbi = ll_s2sbi(sb); - struct ptlrpc_request *request = NULL; - struct lustre_handle dt_conn = {0, }; struct lustre_handle md_conn = {0, }; - struct obd_connect_data *data; - struct inode *root = NULL; - struct obd_device *obd; + struct obd_device *md_obd; struct obd_statfs osfs; - struct lustre_md md; unsigned long sec_flags; __u32 valsize; - int err; - ENTRY; - - obd = class_name2obd(lmv); - if (!obd) { + int err = 0; + ENTRY; + + md_obd = class_name2obd(lmv); + if (!md_obd) { CERROR("MDC %s: not setup or attached\n", lmv); RETURN(-EINVAL); } - obd_set_info(obd->obd_self_export, strlen("async"), "async", - sizeof(async), &async); - if ((*remote & (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) == - (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) { - CERROR("wrong remote flag "LPX64"\n", *remote); - RETURN(-EINVAL); - } - - OBD_ALLOC(data, sizeof(*data)); - if (!data) - RETURN(-ENOMEM); - - data->ocd_connect_flags |= *remote & (OBD_CONNECT_LOCAL | - OBD_CONNECT_REMOTE); - memcpy(data->ocd_nllu, nllu, sizeof(data->ocd_nllu)); - - if (mds_security == NULL) - mds_security = "null"; + obd_set_info(md_obd->obd_self_export, strlen("async"), "async", + sizeof(async), &async); - err = obd_set_info(obd->obd_self_export, strlen("sec"), "sec", + err = obd_set_info(md_obd->obd_self_export, strlen("sec"), "sec", strlen(mds_security), mds_security); + if (err) { CERROR("LMV %s: failed to set security %s, err %d\n", lmv, mds_security, err); - OBD_FREE(data, sizeof(*data)); RETURN(err); } if (pag) { sec_flags = PTLRPC_SEC_FL_PAG; - err = obd_set_info(obd->obd_self_export, + err = obd_set_info(md_obd->obd_self_export, strlen("sec_flags"), "sec_flags", sizeof(sec_flags), &sec_flags); if (err) { @@ -193,14 +171,7 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, } } - if (proc_lustre_fs_root) { - err = lprocfs_register_mountpoint(proc_lustre_fs_root, - sb, lov, lmv); - if (err < 0) - CERROR("could not register mount in /proc/lustre"); - } - - err = obd_connect(&md_conn, obd, &sbi->ll_sb_uuid, data, + err = obd_connect(&md_conn, md_obd, &sbi->ll_sb_uuid, data, OBD_OPT_REAL_CLIENT); if (err == -EBUSY) { CERROR("An MDS (lmv %s) is performing recovery, of which this" @@ -211,14 +182,16 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, CERROR("cannot connect to %s: rc = %d\n", lmv, err); GOTO(out, err); } + sbi->ll_md_exp = class_conn2export(&md_conn); - err = obd_statfs(obd, &osfs, jiffies - HZ); + + err = obd_statfs(md_obd, &osfs, jiffies - HZ); if (err) - GOTO(out_lmv, err); + GOTO(out_disconnect, err); if (!osfs.os_bsize) { CERROR("Invalid block size is detected."); - GOTO(out_lmv, err); + GOTO(out_disconnect, err); } sb->s_magic = LL_SUPER_MAGIC; @@ -246,13 +219,29 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, &valsize, &sbi->ll_remote); if (err) { CERROR("fail to obtain remote flag\n"); - GOTO(out, err); + GOTO(out_disconnect, err); } +out_disconnect: + if (err) + obd_disconnect(sbi->ll_md_exp, 0); +out: + RETURN(err); +} +static int lustre_connect_ost(struct super_block *sb, char *lov, + struct obd_connect_data *data, + char *oss_security, int async, int pag) +{ + struct ll_sb_info *sbi = ll_s2sbi(sb); + struct lustre_handle dt_conn = {0, }; + struct obd_device *obd = NULL; + unsigned long sec_flags; + int err, mdsize; + obd = class_name2obd(lov); if (!obd) { CERROR("OSC %s: not setup or attached\n", lov); - GOTO(out_lmv, err); + GOTO(out, err = -EINVAL); } obd_set_info(obd->obd_self_export, strlen("async"), "async", sizeof(async), &async); @@ -265,7 +254,6 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, if (err) { CERROR("LOV %s: failed to set security %s, err %d\n", lov, oss_security, err); - OBD_FREE(data, sizeof(*data)); RETURN(err); } @@ -288,22 +276,38 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, GOTO(out, err); } else if (err) { CERROR("cannot connect to %s: rc = %d\n", lov, err); - GOTO(out_lmv, err); + GOTO(out, err); } sbi->ll_dt_exp = class_conn2export(&dt_conn); err = lustre_init_dt_desc(sbi); - if (err == 0) { - int mdsize = obd_size_diskmd(sbi->ll_dt_exp, NULL); - obd_init_ea_size(sbi->ll_md_exp, mdsize, - sbi->ll_dt_desc.ld_tgt_count * - sizeof(struct llog_cookie)); + + if (err) { + CWARN("init dt_desc error %d \n", err); + GOTO(out, err = 0); } - + mdsize = obd_size_diskmd(sbi->ll_dt_exp, NULL); + obd_init_ea_size(sbi->ll_md_exp, mdsize, sbi->ll_dt_desc.ld_tgt_count * + sizeof(struct llog_cookie)); +out: + RETURN(err); +} + +extern struct dentry_operations ll_d_ops; + +static int lustre_init_root_inode(struct super_block *sb) +{ + struct ll_sb_info *sbi = ll_s2sbi(sb); + struct ptlrpc_request *request = NULL; + struct inode *root = NULL; + struct lustre_md md; + int err = 0; + ENTRY; + err = md_getstatus(sbi->ll_md_exp, &sbi->ll_rootid); if (err) { CERROR("cannot mds_connect: rc = %d\n", err); - GOTO(out_lov, err); + GOTO(out, err); } CDEBUG(D_SUPER, "rootid "DLID4"\n", OLID4(&sbi->ll_rootid)); @@ -315,7 +319,7 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, NULL, NULL, 0, 0, &request); if (err) { CERROR("md_getattr failed for root: rc = %d\n", err); - GOTO(out_lov, err); + GOTO(out, err); } err = mdc_req2lustre_md(sbi->ll_md_exp, request, 0, @@ -323,7 +327,7 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, if (err) { CERROR("failed to understand root inode md: rc = %d\n", err); ptlrpc_req_finished(request); - GOTO(out_lov, err); + GOTO(out, err); } LASSERT(id_ino(&sbi->ll_rootid) != 0); @@ -340,6 +344,66 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, CERROR("lustre_lite: bad iget4 for root\n"); GOTO(out_root, err = -EBADF); } + sb->s_root = d_alloc_root(root); + sb->s_root->d_op = &ll_d_ops; +out_root: + if (err) + iput(root); +out: + RETURN(err); +} + +int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, + char *gkc, int async, char *mds_security, + char *oss_security, __u32 *nllu, int pag, + __u64 *remote) +{ + struct ll_sb_info *sbi = ll_s2sbi(sb); + struct obd_connect_data *data; + int err; + ENTRY; + + /*process the connect flags*/ + if ((*remote & (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) == + (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) { + CERROR("wrong remote flag "LPX64"\n", *remote); + RETURN(-EINVAL); + } + + OBD_ALLOC(data, sizeof(*data)); + if (!data) + RETURN(-ENOMEM); + + data->ocd_connect_flags |= *remote & (OBD_CONNECT_LOCAL | + OBD_CONNECT_REMOTE); + memcpy(data->ocd_nllu, nllu, sizeof(data->ocd_nllu)); + + if (proc_lustre_fs_root) { + err = lprocfs_register_mountpoint(proc_lustre_fs_root, + sb, lov, lmv); + if (err < 0) + CERROR("could not register mount in /proc/lustre"); + } + + /*connect mds */ + err = lustre_connect_mds(sb, lmv, data, mds_security, async, pag); + if (err) + GOTO(out, err); + + /*connect OST*/ + err = lustre_connect_ost(sb, lov, data, oss_security, async, pag); + if (err) + GOTO(out_lmv, err); + + err = lustre_init_crypto(sb, gkc, data, async); + if (err) { + CERROR("Could not connect to GSS err %d\n", err); + err = 0; + } + /*connect GSS*/ + err = lustre_init_root_inode(sb); + if (err) + GOTO(out_gks, err); err = ll_close_thread_start(&sbi->ll_lcq); if (err) { @@ -357,31 +421,26 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov, /* bug 2805 - set VM readahead to zero */ vm_max_readahead = vm_min_readahead = 0; #endif - - sb->s_root = d_alloc_root(root); - sb->s_root->d_op = &ll_d_ops; - sb->s_flags |= MS_POSIXACL; #ifdef S_PDIROPS CWARN("Enabling PDIROPS\n"); sb->s_flags |= S_PDIROPS; #endif - if (data != NULL) OBD_FREE(data, sizeof(*data)); RETURN(err); out_root: - if (root) - iput(root); -out_lov: - obd_disconnect(sbi->ll_dt_exp, 0); + if (sb->s_root) + dput(sb->s_root); +out_gks: + lustre_destroy_crypto(sb); out_lmv: obd_disconnect(sbi->ll_md_exp, 0); out: if (data != NULL) OBD_FREE(data, sizeof(*data)); lprocfs_unregister_mountpoint(sbi); - return err; + RETURN(err); } void lustre_common_put_super(struct super_block *sb) @@ -393,6 +452,8 @@ void lustre_common_put_super(struct super_block *sb) ll_gns_del_timer(sbi); ll_close_thread_shutdown(sbi->ll_lcq); + lustre_destroy_crypto(sb); + list_del(&sbi->ll_conn_chain); obd_disconnect(sbi->ll_dt_exp, 0); @@ -449,8 +510,8 @@ int ll_set_opt(const char *opt, char *data, int fl) RETURN(fl); } -void ll_options(char *options, char **lov, char **lmv, char **mds_sec, - char **oss_sec, int *async, int *flags) +void ll_options(char *options, char **lov, char **lmv, char **gkc, + char **mds_sec, char **oss_sec, int *async, int *flags) { char *this_char; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) @@ -476,6 +537,8 @@ void ll_options(char *options, char **lov, char **lmv, char **mds_sec, continue; if (!*lmv && (*lmv = ll_read_opt("mdc", this_char))) continue; + if (!*gkc && (*gkc = ll_read_opt("gkc", this_char))) + continue; if (!strncmp(this_char, "lasync", strlen("lasync"))) { *async = 1; continue; @@ -511,13 +574,13 @@ void ll_lli_init(struct ll_inode_info *lli) lli->lli_mds_exec_och = NULL; lli->lli_open_fd_read_count = lli->lli_open_fd_write_count = 0; lli->lli_open_fd_exec_count = 0; + lli->lli_key_info = NULL; } int ll_fill_super(struct super_block *sb, void *data, int silent) { struct ll_sb_info *sbi; - char *lov = NULL; - char *lmv = NULL; + char *lov = NULL, *lmv = NULL, *gkc = NULL; char *mds_sec = NULL; char *oss_sec = NULL; int async, err; @@ -532,21 +595,16 @@ int ll_fill_super(struct super_block *sb, void *data, int silent) RETURN(-ENOMEM); sbi->ll_flags |= LL_SBI_READAHEAD; - ll_options(data, &lov, &lmv, &mds_sec, &oss_sec, + ll_options(data, &lov, &lmv, &gkc, &mds_sec, &oss_sec, &async, &sbi->ll_flags); - if (!lov) { - CERROR("no osc\n"); - GOTO(out, err = -EINVAL); - } - - if (!lmv) { - CERROR("no mdc\n"); + if (!lov || !lmv) { + CERROR("no osc %p or no mdc %p\n", lov, lmv); GOTO(out, err = -EINVAL); } - err = lustre_common_fill_super(sb, lmv, lov, async, mds_sec, oss_sec, - nllu, 0, &remote_flag); + err = lustre_common_fill_super(sb, lmv, lov, gkc, async, mds_sec, + oss_sec, nllu, 0, &remote_flag); EXIT; out: if (err) @@ -738,8 +796,7 @@ static void lustre_manual_cleanup(struct ll_sb_info *sbi) struct obd_device *obd; int next = 0; - while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) != NULL) - { + while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) != NULL) { int err; lustre_cfg_bufs_reset(&bufs, obd->obd_name); @@ -763,10 +820,115 @@ static void lustre_manual_cleanup(struct ll_sb_info *sbi) class_del_profile(sbi->ll_lmd->lmd_profile); } +static int lustre_process_profile(struct super_block *sb, + struct lustre_mount_data *lmd, + char **lov, char **lmv, char **gkc) +{ + struct ll_sb_info *sbi = ll_s2sbi(sb); + struct lustre_profile *lprof; + struct config_llog_instance cfg; + int len, err = 0; + + ENTRY; + + if (!lmd->lmd_profile) + RETURN(0); + + if (lmd->lmd_mds[0] == '\0') { + CERROR("no mds name\n"); + GOTO(out, err = -EINVAL); + } + lmd->lmd_mds_security[sizeof(lmd->lmd_mds_security) - 1] = 0; + lmd->lmd_oss_security[sizeof(lmd->lmd_oss_security) - 1] = 0; + + OBD_ALLOC(sbi->ll_lmd, sizeof(*sbi->ll_lmd)); + if (sbi->ll_lmd == NULL) + GOTO(out, err = -ENOMEM); + memcpy(sbi->ll_lmd, lmd, sizeof(*lmd)); + + /* generate a string unique to this super, let's try + the address of the super itself.*/ + len = (sizeof(sb) * 2) + 1; + OBD_ALLOC(sbi->ll_instance, len); + if (sbi->ll_instance == NULL) + GOTO(out, err = -ENOMEM); + sprintf(sbi->ll_instance, "%p", sb); + + cfg.cfg_instance = sbi->ll_instance; + cfg.cfg_uuid = sbi->ll_sb_uuid; + cfg.cfg_local_nid = lmd->lmd_local_nid; + err = lustre_process_log(lmd, lmd->lmd_profile, &cfg, 0); + if (err < 0) { + CERROR("Unable to process log: %s\n", lmd->lmd_profile); + GOTO(out, err); + } + + lprof = class_get_profile(lmd->lmd_profile); + if (lprof == NULL) { + CERROR("No profile found: %s\n", lmd->lmd_profile); + GOTO(out, err = -EINVAL); + } + + OBD_ALLOC(*lov, strlen(lprof->lp_lov) + + strlen(sbi->ll_instance) + 2); + sprintf(*lov, "%s-%s", lprof->lp_lov, sbi->ll_instance); + + OBD_ALLOC(*lmv, strlen(lprof->lp_lmv) + + strlen(sbi->ll_instance) + 2); + sprintf(*lmv, "%s-%s", lprof->lp_lmv, sbi->ll_instance); + + if (lprof->lp_gkc) { + OBD_ALLOC(*gkc, strlen(lprof->lp_gkc) + + strlen(sbi->ll_instance) + 2); + sprintf(*gkc, "%s-%s", lprof->lp_gkc, sbi->ll_instance); + } +out: + RETURN(err); +} + +static int lustre_clean_profile(struct ll_sb_info *sbi, int force_umount) +{ + struct lustre_mount_data *lmd = sbi->ll_lmd; + struct config_llog_instance cfg; + char *cl_prof; + int len, err = 0; + ENTRY; + + if (!lmd) + RETURN(err); + + len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean") + 1; + + if (force_umount) { + CERROR("force umount, doing manual cleanup\n"); + lustre_manual_cleanup(sbi); + GOTO(free_lmd, 0); + + } + if (sbi->ll_instance != NULL) { + cfg.cfg_instance = sbi->ll_instance; + cfg.cfg_uuid = sbi->ll_sb_uuid; + + OBD_ALLOC(cl_prof, len); + sprintf(cl_prof, "%s-clean", lmd->lmd_profile); + err = lustre_process_log(lmd, cl_prof, &cfg, 0); + if (err < 0) { + CERROR("Unable to process log: %s\n", cl_prof); + lustre_manual_cleanup(sbi); + } + OBD_FREE(cl_prof, len); + } +free_lmd: + if (sbi->ll_instance) + OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1); + OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd)); + RETURN(err); +} + int lustre_fill_super(struct super_block *sb, void *data, int silent) { struct lustre_mount_data * lmd = data; - char *lov = NULL, *lmv = NULL; + char *lov = NULL, *lmv = NULL, *gkc = NULL; struct ll_sb_info *sbi; int err; ENTRY; @@ -781,69 +943,17 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) sbi->ll_flags |= LL_SBI_READAHEAD; - if (lmd->lmd_profile) { - struct lustre_profile *lprof; - struct config_llog_instance cfg; - int len; - - if (lmd->lmd_mds[0] == '\0') { - CERROR("no mds name\n"); - GOTO(out_free, err = -EINVAL); - } - lmd->lmd_mds_security[sizeof(lmd->lmd_mds_security) - 1] = 0; - lmd->lmd_oss_security[sizeof(lmd->lmd_oss_security) - 1] = 0; - - OBD_ALLOC(sbi->ll_lmd, sizeof(*sbi->ll_lmd)); - if (sbi->ll_lmd == NULL) - GOTO(out_free, err = -ENOMEM); - memcpy(sbi->ll_lmd, lmd, sizeof(*lmd)); - - /* generate a string unique to this super, let's try - the address of the super itself.*/ - len = (sizeof(sb) * 2) + 1; - OBD_ALLOC(sbi->ll_instance, len); - if (sbi->ll_instance == NULL) - GOTO(out_free, err = -ENOMEM); - sprintf(sbi->ll_instance, "%p", sb); - - cfg.cfg_instance = sbi->ll_instance; - cfg.cfg_uuid = sbi->ll_sb_uuid; - cfg.cfg_local_nid = lmd->lmd_local_nid; - err = lustre_process_log(lmd, lmd->lmd_profile, &cfg, 0); - if (err < 0) { - CERROR("Unable to process log: %s\n", lmd->lmd_profile); - GOTO(out_free, err); - } - - lprof = class_get_profile(lmd->lmd_profile); - if (lprof == NULL) { - CERROR("No profile found: %s\n", lmd->lmd_profile); - GOTO(out_free, err = -EINVAL); - } - if (lov) - OBD_FREE(lov, strlen(lov) + 1); - OBD_ALLOC(lov, strlen(lprof->lp_lov) + - strlen(sbi->ll_instance) + 2); - sprintf(lov, "%s-%s", lprof->lp_lov, sbi->ll_instance); - - if (lmv) - OBD_FREE(lmv, strlen(lmv) + 1); - OBD_ALLOC(lmv, strlen(lprof->lp_lmv) + - strlen(sbi->ll_instance) + 2); - sprintf(lmv, "%s-%s", lprof->lp_lmv, sbi->ll_instance); - } - - if (!lov) { - CERROR("no osc\n"); - GOTO(out_free, err = -EINVAL); + err = lustre_process_profile(sb, lmd, &lov, &lmv, &gkc); + if (err) { + CERROR("Can not process the profile err %d \n", err); + GOTO(out_free, err); } - - if (!lmv) { - CERROR("no mdc\n"); + if (!lov || !lmv) { + CERROR("no osc %p or no mdc %p \n", lov, lmv); GOTO(out_free, err = -EINVAL); } - err = lustre_common_fill_super(sb, lmv, lov, lmd->lmd_async, + err = lustre_common_fill_super(sb, lmv, lov, gkc, lmd->lmd_async, lmd->lmd_mds_security, lmd->lmd_oss_security, &lmd->lmd_nllu, lmd->lmd_pag, @@ -857,36 +967,15 @@ out_dev: OBD_FREE(lmv, strlen(lmv) + 1); if (lov) OBD_FREE(lov, strlen(lov) + 1); - + if (gkc) + OBD_FREE(gkc, strlen(gkc) + 1); + RETURN(err); - out_free: - if (sbi->ll_lmd) { - int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1; - int err; - - if (sbi->ll_instance != NULL) { - struct lustre_mount_data *lmd = sbi->ll_lmd; - struct config_llog_instance cfg; - char *cl_prof; - - cfg.cfg_instance = sbi->ll_instance; - cfg.cfg_uuid = sbi->ll_sb_uuid; - - OBD_ALLOC(cl_prof, len); - sprintf(cl_prof, "%s-clean", lmd->lmd_profile); - err = lustre_process_log(lmd, cl_prof, &cfg, 0); - if (err < 0) { - CERROR("Unable to process log: %s\n", cl_prof); - lustre_manual_cleanup(sbi); - } - OBD_FREE(cl_prof, len); - OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1); - } - OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd)); - } + lustre_clean_profile(sbi, 0); lustre_free_sbi(sb); - goto out_dev; + GOTO(out_dev, err); + } /* lustre_fill_super */ void lustre_put_super(struct super_block *sb) @@ -903,36 +992,7 @@ void lustre_put_super(struct super_block *sb) obd = NULL; lustre_common_put_super(sb); - if (sbi->ll_lmd != NULL) { - char *cl_prof; - int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1; - int err; - struct config_llog_instance cfg; - - if (force_umount) { - CERROR("force umount, doing manual cleanup\n"); - lustre_manual_cleanup(sbi); - GOTO(free_lmd, 0); - } - - cfg.cfg_instance = sbi->ll_instance; - cfg.cfg_uuid = sbi->ll_sb_uuid; - - OBD_ALLOC(cl_prof, len); - sprintf(cl_prof, "%s-clean", sbi->ll_lmd->lmd_profile); - err = lustre_process_log(sbi->ll_lmd, cl_prof, &cfg, 0); - if (err < 0) { - CERROR("Unable to process log: %s, doing manual cleanup" - "\n", cl_prof); - lustre_manual_cleanup(sbi); - } - - OBD_FREE(cl_prof, len); - free_lmd: - OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd)); - OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1); - } - + lustre_clean_profile(sbi, force_umount); lustre_free_sbi(sb); EXIT; @@ -1093,7 +1153,7 @@ void ll_clear_inode(struct inode *inode) (struct lov_stripe_md **) &lli->lli_mea); lli->lli_mea = NULL; } - + ll_crypto_destroy_inode_key(inode); if (lli->lli_symlink_name) { OBD_FREE(lli->lli_symlink_name, strlen(lli->lli_symlink_name) + 1); @@ -1187,22 +1247,31 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) * inode ourselves so we can call obdo_from_inode() always. */ if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN /*| ATTR_RAW*/) : ~0)) { struct lustre_md md; + void *key = NULL; + int key_size = 0; OBD_ALLOC(op_data, sizeof(*op_data)); if (op_data == NULL) RETURN(-ENOMEM); ll_prepare_mdc_data(op_data, inode, NULL, NULL, 0, 0); + if (ia_valid & (ATTR_UID | ATTR_GID)) { + rc = ll_crypto_get_mac(inode, attr, NULL, 0, &key, + &key_size); + } rc = md_setattr(sbi->ll_md_exp, op_data, - attr, NULL, 0, NULL, 0, &request); + attr, key, key_size, NULL, 0, NULL, + 0, &request); OBD_FREE(op_data, sizeof(*op_data)); + + if (key && key_size) + OBD_FREE(key, key_size); if (rc) { ptlrpc_req_finished(request); if (rc != -EPERM && rc != -EACCES) CERROR("md_setattr fails: rc = %d\n", rc); RETURN(rc); } - rc = mdc_req2lustre_md(sbi->ll_md_exp, request, 0, sbi->ll_dt_exp, &md); if (rc) { @@ -1834,6 +1903,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) struct mea *mea = md->mea; struct posix_acl *posix_acl = md->posix_acl; struct ll_sb_info *sbi = ll_i2sbi(inode); + struct lustre_key *mkey = md->key; ENTRY; LASSERT((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0)); @@ -1969,6 +2039,11 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->valid & OBD_MD_FLSIZE) set_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags); + if (mkey != NULL) { + LASSERT(body->valid & OBD_MD_FLKEY); + ll_crypto_init_inode_key(inode, mkey); + } + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) inode->i_dev = (kdev_t)id_group(&lli->lli_id); #endif @@ -2139,7 +2214,7 @@ int ll_iocontrol(struct inode *inode, struct file *file, attr.ia_valid |= ATTR_ATTR_FLAG; rc = md_setattr(sbi->ll_md_exp, op_data, - &attr, NULL, 0, NULL, 0, &req); + &attr, NULL, 0, NULL, 0, NULL, 0, &req); OBD_FREE(op_data, sizeof(*op_data)); if (rc) { ptlrpc_req_finished(req); @@ -2305,7 +2380,6 @@ int ll_get_fid(struct obd_export *exp, struct lustre_id *idp, return rc; } - int ll_flush_cred(struct inode *inode) { struct ll_sb_info *sbi = ll_i2sbi(inode); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 9cad4e7..113b902 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -383,7 +383,12 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, icbd.icbd_childp = &dentry; icbd.icbd_parent = parent; ll_inode2id(&pid, parent); - + + /*ONLY need key for open_create file*/ + rc = ll_crypto_init_it_key(parent, it); + if (rc != 0) + GOTO(out, retval = ERR_PTR(rc)); + rc = md_intent_lock(ll_i2mdexp(parent), &pid, (char *)dentry->d_name.name, dentry->d_name.len, NULL, 0, NULL, it, flags, &req, ll_mdc_blocking_ast); @@ -576,7 +581,8 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev) struct inode *dir = nd->dentry->d_inode; struct ll_sb_info *sbi = ll_i2sbi(dir); struct mdc_op_data *op_data; - int err = -EMLINK; + int err = -EMLINK, key_size = 0; + void *key = NULL; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n", @@ -587,8 +593,9 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev) switch (mode & S_IFMT) { case 0: - case S_IFREG: + case S_IFREG: mode |= S_IFREG; /* for mode = 0 case, fallthrough */ + ll_crypto_create_key(dir, mode, &key, &key_size); case S_IFCHR: case S_IFBLK: case S_IFIFO: @@ -599,8 +606,7 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev) ll_prepare_mdc_data(op_data, dir, NULL, (char *)nd->last.name, nd->last.len, 0); - - err = md_create(sbi->ll_md_exp, op_data, NULL, 0, mode, + err = md_create(sbi->ll_md_exp, op_data, key, key_size, mode, current->fsuid, current->fsgid, rdev, &request); OBD_FREE(op_data, sizeof(*op_data)); @@ -614,6 +620,8 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev) default: err = -EINVAL; } + if (key && key_size) + OBD_FREE(key, key_size); RETURN(err); } @@ -637,6 +645,7 @@ static int ll_mknod(struct inode *dir, struct dentry *dchild, case 0: case S_IFREG: mode |= S_IFREG; /* for mode = 0 case, fallthrough */ + case S_IFCHR: case S_IFBLK: case S_IFIFO: diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 434febc..634a454 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -183,6 +183,16 @@ out_unlock: up(&lli->lli_size_sem); } /* ll_truncate */ +struct ll_async_page *llap_cast_private(struct page *page) +{ + struct ll_async_page *llap = (struct ll_async_page *)page->private; + + LASSERTF(llap == NULL || llap->llap_magic == LLAP_MAGIC, + "page %p private %lu gave magic %d which != %d\n", + page, page->private, llap->llap_magic, LLAP_MAGIC); + return llap; +} + int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { @@ -384,17 +394,6 @@ static struct obd_async_page_ops ll_async_page_ops = { }; -struct ll_async_page *llap_cast_private(struct page *page) -{ - struct ll_async_page *llap = (struct ll_async_page *)page->private; - - LASSERTF(llap == NULL || llap->llap_magic == LLAP_MAGIC, - "page %p private %lu gave magic %d which != %d\n", - page, page->private, llap->llap_magic, LLAP_MAGIC); - - return llap; -} - /* XXX have the exp be an argument? */ struct ll_async_page *llap_from_page(struct page *page, unsigned origin) { @@ -408,16 +407,17 @@ struct ll_async_page *llap_from_page(struct page *page, unsigned origin) LASSERTF(origin < LLAP__ORIGIN_MAX, "%u\n", origin); llap = llap_cast_private(page); - if (llap != NULL) + if (llap != NULL) { GOTO(out, llap); - + } exp = ll_i2dtexp(page->mapping->host); if (exp == NULL) RETURN(ERR_PTR(-EINVAL)); - + OBD_ALLOC(llap, sizeof(*llap)); - if (llap == NULL) + if (llap == NULL) { RETURN(ERR_PTR(-ENOMEM)); + } llap->llap_magic = LLAP_MAGIC; INIT_LIST_HEAD(&llap->llap_pending_write); rc = obd_prep_async_page(exp, ll_i2info(inode)->lli_smd, NULL, page, @@ -430,8 +430,10 @@ struct ll_async_page *llap_from_page(struct page *page, unsigned origin) CDEBUG(D_CACHE, "llap %p page %p cookie %p obj off "LPU64"\n", llap, page, llap->llap_cookie, (obd_off)page->index << PAGE_SHIFT); - /* also zeroing the PRIVBITS low order bitflags */ + __set_page_ll_data(page, llap); + + /* also zeroing the PRIVBITS low order bitflags */ llap->llap_page = page; spin_lock(&sbi->ll_lock); @@ -469,7 +471,6 @@ static int queue_or_sync_write(struct obd_export *exp, rc = oig_init(&oig); if (rc) GOTO(out, rc); - rc = obd_queue_group_io(exp, lsm, NULL, oig, llap->llap_cookie, OBD_BRW_WRITE, 0, to, 0, ASYNC_READY | ASYNC_URGENT | ASYNC_COUNT_STABLE | @@ -703,7 +704,6 @@ void ll_removepage(struct page *page) EXIT; return; } - llap = llap_from_page(page, 0); if (IS_ERR(llap)) { CERROR("page %p ind %lu couldn't find llap: %ld\n", page, @@ -765,10 +765,11 @@ static int ll_issue_page_read(struct obd_export *exp, page_cache_get(page); llap->llap_defer_uptodate = defer; llap->llap_ra_used = 0; + rc = obd_queue_group_io(exp, ll_i2info(page->mapping->host)->lli_smd, NULL, oig, llap->llap_cookie, OBD_BRW_READ, 0, PAGE_SIZE, 0, ASYNC_COUNT_STABLE | ASYNC_READY - | ASYNC_URGENT); + | ASYNC_URGENT); if (rc) { LL_CDEBUG_PAGE(D_ERROR, page, "read queue failed: rc %d\n", rc); page_cache_release(page); @@ -1057,7 +1058,7 @@ int ll_readpage(struct file *filp, struct page *page) llap = llap_from_page(page, LLAP_ORIGIN_READPAGE); if (IS_ERR(llap)) GOTO(out, rc = PTR_ERR(llap)); - + if (ll_i2sbi(inode)->ll_flags & LL_SBI_READAHEAD) ras_update(ll_i2sbi(inode), &fd->fd_ras, page->index, llap->llap_defer_uptodate); diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index ff27c5c..02198dc 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1357,7 +1357,8 @@ request: static int lmv_setattr(struct obd_export *exp, struct mdc_op_data *data, struct iattr *iattr, void *ea, int ealen, void *ea2, - int ea2len, struct ptlrpc_request **request) + int ea2len, void *ea3, int ea3len, + struct ptlrpc_request **request) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; @@ -1381,7 +1382,8 @@ static int lmv_setattr(struct obd_export *exp, struct mdc_op_data *data, data->id1 = obj->objs[i].id; rc = md_setattr(lmv->tgts[id_group(&data->id1)].ltd_exp, - data, iattr, ea, ealen, ea2, ea2len, &req); + data, iattr, ea, ealen, ea2, ea2len, + ea3, ea3len, &req); if (id_equal_fid(&obj->id, &obj->objs[i].id)) { /* @@ -1400,7 +1402,8 @@ static int lmv_setattr(struct obd_export *exp, struct mdc_op_data *data, } else { LASSERT(id_group(&data->id1) < lmv->desc.ld_tgt_count); rc = md_setattr(lmv->tgts[id_group(&data->id1)].ltd_exp, - data, iattr, ea, ealen, ea2, ea2len, request); + data, iattr, ea, ealen, ea2, ea2len, ea3, + ea3len, request); if (rc == 0) { body = lustre_msg_buf((*request)->rq_repmsg, 0, sizeof(*body)); @@ -1999,8 +2002,10 @@ int lmv_set_info(struct obd_export *exp, obd_count keylen, RETURN(rc); } - if ((keylen == strlen("flush_cred") && - strcmp(key, "flush_cred") == 0)) { + if (((keylen == strlen("flush_cred") && + strcmp(key, "flush_cred") == 0)) || + ((keylen == strlen("crypto_type") && + strcmp(key, "crypto_type") == 0))) { int rc = 0, i; for (i = 0, tgt = lmv->tgts; i < lmv->desc.ld_tgt_count; diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 2388527..12791c1 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2013,6 +2013,7 @@ static int lov_get_info(struct obd_export *exp, __u32 keylen, } LDLM_ERROR(data->lock, "lock on inode without such object"); dump_lsm(D_ERROR, data->lsm); + portals_debug_dumpstack(NULL); RETURN(-ENXIO); } else if (keylen >= strlen("size_to_stripe") && strcmp(key, "size_to_stripe") == 0) { @@ -2139,7 +2140,7 @@ static int lov_set_info(struct obd_export *exp, obd_count keylen, spin_unlock(&lov->lov_lock); RETURN(rc); - } else if (KEY_IS("flush_cred")) { + } else if (KEY_IS("flush_cred") || KEY_IS("crypto_cb")) { struct lov_tgt_desc *tgt; int rc = 0, i; diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 481a5b7..52dde66 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -79,6 +79,7 @@ struct fsfilt_cb_data { #define XATTR_LUSTRE_MDS_MEA_EA "mea" #define XATTR_LUSTRE_MDS_MID_EA "mid" #define XATTR_LUSTRE_MDS_SID_EA "sid" +#define XATTR_LUSTRE_MDS_KEY_EA "key" /* * We don't currently need any additional blocks for rmdir and @@ -512,6 +513,11 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle, XATTR_LUSTRE_MDS_MID_EA, lmm, lmm_size); break; + case EA_KEY: + rc = fsfilt_ext3_set_xattr(inode, handle, + XATTR_LUSTRE_MDS_KEY_EA, + lmm, lmm_size); + break; default: return -EINVAL; } @@ -545,6 +551,11 @@ static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, XATTR_LUSTRE_MDS_MID_EA, lmm, lmm_size); break; + case EA_KEY: + rc = fsfilt_ext3_get_xattr(inode, + XATTR_LUSTRE_MDS_KEY_EA, + lmm, lmm_size); + break; default: return -EINVAL; } diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h index 587a24e..6a0abe9 100644 --- a/lustre/mdc/mdc_internal.h +++ b/lustre/mdc/mdc_internal.h @@ -29,9 +29,11 @@ int mdc_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, void mdc_getattr_pack(struct lustre_msg *msg, int offset, __u64 valid, int flags, struct mdc_op_data *data); + void mdc_open_pack(struct lustre_msg *msg, int offset, - struct mdc_op_data *op_data, __u32 mode, __u64 rdev, - __u32 flags, const void *lmm, int lmmlen); + struct mdc_op_data *op_data, __u32 mode, + __u64 rdev, __u32 flags, const void *lmm, + int lmmlen, void *key, int keylen); void mdc_readdir_pack(struct ptlrpc_request *req, int req_offset, __u64 offset, __u32 size, struct lustre_id *mdc_id); void mdc_close_pack(struct ptlrpc_request *req, int offset, struct obdo *oa, diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 07a6195..901e4a1 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -50,26 +50,11 @@ void mdc_readdir_pack(struct ptlrpc_request *req, int req_offset, b->nlink = size; /* !! */ } -static __u32 mds_pack_open_flags(__u32 flags) -{ - return - (flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC | - MDS_OPEN_DELAY_CREATE | MDS_OPEN_HAS_EA | - MDS_OPEN_HAS_OBJS)) | - ((flags & O_CREAT) ? MDS_OPEN_CREAT : 0) | - ((flags & O_EXCL) ? MDS_OPEN_EXCL : 0) | - ((flags & O_TRUNC) ? MDS_OPEN_TRUNC : 0) | - ((flags & O_APPEND) ? MDS_OPEN_APPEND : 0) | - ((flags & O_SYNC) ? MDS_OPEN_SYNC : 0) | - ((flags & O_DIRECTORY) ? MDS_OPEN_DIRECTORY : 0) | - 0; -} - /* packing of MDS records */ void mdc_open_pack(struct lustre_msg *msg, int offset, struct mdc_op_data *op_data, __u32 mode, __u64 rdev, __u32 flags, const void *lmm, - int lmmlen) + int lmmlen, void *key, int keylen) { struct mds_rec_create *rec; char *tmp; @@ -97,6 +82,11 @@ void mdc_open_pack(struct lustre_msg *msg, int offset, tmp = lustre_msg_buf(msg, offset + 2, lmmlen); memcpy (tmp, lmm, lmmlen); } + if (key) { + rec->cr_flags |= MDS_OPEN_HAS_KEY; + tmp = lustre_msg_buf(msg, offset + 3, keylen); + memcpy(tmp, key, keylen); + } } void mdc_getattr_pack(struct lustre_msg *msg, int offset, diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index b0856bb..e89e46c 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "mdc_internal.h" @@ -239,13 +240,18 @@ int mdc_enqueue(struct obd_export *exp, reqsize[0] = lustre_secdesc_size(); if (it->it_op & IT_OPEN) { + struct lustre_intent_data *lustre_data = + (struct lustre_intent_data *) it->d.fs_data; it->it_create_mode |= S_IFREG; it->it_create_mode &= ~current->fs->umask; reqsize[req_buffers++] = sizeof(struct mds_rec_create); reqsize[req_buffers++] = data->namelen + 1; reqsize[req_buffers++] = obddev->u.cli.cl_max_mds_easize; - + /*pack the lustre key*/ + if (lustre_data->it_key_size > 0 && lustre_data->it_key) + reqsize[req_buffers++] = lustre_data->it_key_size; + req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_DLM_VERSION, LDLM_ENQUEUE, req_buffers, reqsize, NULL); if (!req) @@ -262,15 +268,18 @@ int mdc_enqueue(struct obd_export *exp, /* pack the intended request */ mdc_open_pack(req->rq_reqmsg, MDS_REQ_INTENT_REC_OFF, data, - it->it_create_mode, 0, it->it_flags, lmm, lmmsize); + it->it_create_mode, 0, it->it_flags, lmm, lmmsize, + lustre_data->it_key, lustre_data->it_key_size); /* get ready for the reply */ - repsize[3] = 4; - repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES); - reply_buffers = 5; - req->rq_replen = lustre_msg_size(5, repsize); + reply_buffers = 3; + repsize[reply_buffers++] = sizeof(int); + repsize[reply_buffers++] = xattr_acl_size(LL_ACL_MAX_ENTRIES); + repsize[reply_buffers++] = sizeof(int); + repsize[reply_buffers++] = sizeof(struct crypto_key); + req->rq_replen = lustre_msg_size(reply_buffers, repsize); } else if (it->it_op & (IT_GETATTR | IT_LOOKUP | IT_CHDIR)) { __u64 valid = data->valid | OBD_MD_FLNOTOBD | OBD_MD_FLEASIZE | - OBD_MD_FLACL; + OBD_MD_FLACL | OBD_MD_FLKEY; /* we don't expect xattr retrieve could reach here */ LASSERT(!(valid & (OBD_MD_FLXATTR | OBD_MD_FLXATTRLIST))); @@ -297,10 +306,12 @@ int mdc_enqueue(struct obd_export *exp, valid, it->it_flags, data); /* get ready for the reply */ - repsize[3] = 4; - repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES); - reply_buffers = 5; - req->rq_replen = lustre_msg_size(5, repsize); + reply_buffers = 3; + repsize[reply_buffers++] = sizeof(int); + repsize[reply_buffers++] = xattr_acl_size(LL_ACL_MAX_ENTRIES); + repsize[reply_buffers++] = sizeof(int); + repsize[reply_buffers++] = sizeof(struct crypto_key); + req->rq_replen = lustre_msg_size(reply_buffers, repsize); } else if (it->it_op == IT_READDIR) { policy.l_inodebits.bits = MDS_INODELOCK_UPDATE; req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_DLM_VERSION, @@ -404,7 +415,8 @@ int mdc_enqueue(struct obd_export *exp, /* We know what to expect, so we do any byte flipping required here */ LASSERT(reply_buffers == 5 || reply_buffers == 4 || - reply_buffers == 3 || reply_buffers == 1); + reply_buffers == 3 || reply_buffers == 1 || + reply_buffers == 6 || reply_buffers == 7); if (reply_buffers >= 3) { struct mds_body *body; @@ -433,7 +445,8 @@ int mdc_enqueue(struct obd_export *exp, LASSERT(replayea); memcpy(replayea, eadata, body->eadatasize); - LASSERT(req->rq_reqmsg->bufcount == 6); + LASSERT(req->rq_reqmsg->bufcount == 6 || + req->rq_reqmsg->bufcount == 7); req->rq_reqmsg->buflens[5] = body->eadatasize; /* If this isn't the last buffer, we might * have to shift other data around. */ diff --git a/lustre/mdc/mdc_reint.c b/lustre/mdc/mdc_reint.c index 88ec501..b349b88 100644 --- a/lustre/mdc/mdc_reint.c +++ b/lustre/mdc/mdc_reint.c @@ -71,7 +71,8 @@ static int mdc_reint(struct ptlrpc_request *request, * setattr portal. */ int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data, struct iattr *iattr, void *ea, int ealen, void *ea2, - int ea2len, struct ptlrpc_request **request) + int ea2len, void *ea3, int ea3len, + struct ptlrpc_request **request) { struct ptlrpc_request *req; struct mds_rec_setattr *rec; @@ -87,6 +88,8 @@ int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data, bufcount++; if (ea2len > 0) bufcount++; + if (ea3len > 0) + bufcount++; } req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION, @@ -107,7 +110,7 @@ int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data, CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n", LTIME_S(iattr->ia_mtime), LTIME_S(iattr->ia_ctime)); mdc_setattr_pack(req->rq_reqmsg, 1, data, iattr, ea, ealen, - ea2, ea2len); + ea2, ea2len, ea3, ea3len); /* prepare the reply buffer */ diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 21dd245..8362bd8 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "mdc_internal.h" #define REQUEST_MINOR 244 @@ -121,6 +122,11 @@ int mdc_getattr_common(struct obd_export *exp, unsigned int ea_size, reqbody = lustre_msg_buf(req->rq_reqmsg, 1, sizeof(*reqbody)); LASSERT(!(reqbody->valid & OBD_MD_FLACL)); + if (reqbody->valid & OBD_MD_FLKEY) { + repsize[bufcount++] = 5; + repsize[bufcount++] = sizeof(struct lustre_key); + } + req->rq_replen = lustre_msg_size(bufcount, repsize); mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL); @@ -322,16 +328,82 @@ int mdc_store_inode_generation(struct obd_export *exp, return 0; } +static int mdc_unpack_acl(struct obd_export *exp_lmv, struct ptlrpc_request *req, + unsigned int *offset, struct lustre_md *md) +{ + struct posix_acl *acl; + struct mds_remote_perm *perm; + int size, acl_off = 0, rc = 0; + void *buf; + + /* if anything wrong when unpacking md, we don't check acl + * stuff, for simplicity + */ + if (md->body->valid & OBD_MD_FLACL) { + acl_off = *offset; + if (md->body->valid & OBD_MD_FLRMTACL) { + + buf = lustre_swab_repbuf(req, acl_off++, sizeof(*perm), + lustre_swab_remote_perm); + if (buf == NULL) { + CERROR("Can't unpack remote perm\n"); + RETURN(0); + } + OBD_ALLOC(perm, sizeof(*perm)); + if (!perm) + RETURN(-ENOMEM); + memcpy(perm, buf, sizeof(*perm)); + md->remote_perm = perm; + *offset = acl_off; + } else { + size = le32_to_cpu(*(__u32 *) lustre_msg_buf( + req->rq_repmsg, acl_off++, 4)); + buf = lustre_msg_buf(req->rq_repmsg, acl_off++, size); + + acl = posix_acl_from_xattr(buf, size); + *offset = acl_off; + if (IS_ERR(acl)) { + rc = PTR_ERR(acl); + CERROR("convert xattr to acl failed: %d\n", rc); + RETURN(0); + } else if (acl) { + rc = posix_acl_valid(acl); + if (rc) { + CERROR("acl valid error: %d\n", rc); + posix_acl_release(acl); + RETURN(0); + } + } + md->posix_acl = acl; + } + } + RETURN(rc); +} +static int mdc_unpack_gskey(struct obd_export *exp_lmv, struct ptlrpc_request *req, + unsigned int *offset, struct lustre_md *md) +{ + int key_off = 0, rc = 0, size = 0; + void *buf; + + key_off = *offset; + if (md->body->valid & OBD_MD_FLKEY) { + size = le32_to_cpu(*(__u32 *) lustre_msg_buf(req->rq_repmsg, + key_off++, 4)); + buf = lustre_msg_buf(req->rq_repmsg, key_off++, size); + + CDEBUG(D_INFO, "buf %p key_off %d size %d \n", + buf, key_off, size); + md->key = (struct lustre_key *)buf; + *offset = key_off; + } + RETURN(rc); +} int mdc_req2lustre_md(struct obd_export *exp_lmv, struct ptlrpc_request *req, unsigned int offset, struct obd_export *exp_lov, struct lustre_md *md) { struct lov_mds_md *lmm; - struct posix_acl *acl; - struct mds_remote_perm *perm; - void *buf; - int size, acl_off; - int rc = 0; + int rc = 0, reply_off; ENTRY; LASSERT(md != NULL); @@ -395,53 +467,17 @@ int mdc_req2lustre_md(struct obd_export *exp_lmv, struct ptlrpc_request *req, S_ISSOCK(md->body->mode)); } - /* if anything wrong when unpacking md, we don't check acl - * stuff, for simplicity - */ - if (rc) - RETURN(rc); - - if (md->body->valid & OBD_MD_FLACL) { - acl_off = (md->body->valid & OBD_MD_FLEASIZE) ? + reply_off = (md->body->valid & OBD_MD_FLEASIZE) ? (offset + 2) : (offset + 1); - - if (md->body->valid & OBD_MD_FLRMTACL) { - - buf = lustre_swab_repbuf(req, acl_off, sizeof(*perm), - lustre_swab_remote_perm); - if (buf == NULL) { - CERROR("Can't unpack remote perm\n"); - RETURN(0); - } - - OBD_ALLOC(perm, sizeof(*perm)); - if (!perm) - RETURN(0); - memcpy(perm, buf, sizeof(*perm)); - - md->remote_perm = perm; - } else { - size = le32_to_cpu(*(__u32 *) lustre_msg_buf( - req->rq_repmsg, acl_off, 4)); - buf = lustre_msg_buf(req->rq_repmsg, acl_off + 1, size); - - acl = posix_acl_from_xattr(buf, size); - if (IS_ERR(acl)) { - rc = PTR_ERR(acl); - CERROR("convert xattr to acl failed: %d\n", rc); - RETURN(0); - } else if (acl) { - rc = posix_acl_valid(acl); - if (rc) { - CERROR("acl valid error: %d\n", rc); - posix_acl_release(acl); - RETURN(0); - } - } - - md->posix_acl = acl; - } + rc = mdc_unpack_acl(exp_lmv, req, &reply_off, md); + if (rc) { + CERROR("upack acl error %d \n", rc); + RETURN(rc); } + + rc = mdc_unpack_gskey(exp_lmv, req, &reply_off, md); + if (rc) + RETURN(rc); RETURN(rc); } @@ -847,8 +883,8 @@ int mdc_set_info(struct obd_export *exp, obd_count keylen, exp->exp_obd->obd_name, imp->imp_initial_recov); RETURN(0); - } else if (keylen >= strlen("mds_type") && - strcmp(key, "mds_type") == 0) { + } else if ((keylen >= strlen("crypto_type")) && + strcmp(key, "crypto_type") == 0) { struct ptlrpc_request *req; char *bufs[2] = {key, val}; int rc, size[2] = {keylen, vallen}; diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index bd29028..41b73c5 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -56,6 +56,7 @@ #include #include #include +#include #include "mds_internal.h" #include @@ -1059,20 +1060,26 @@ int mds_pack_xattr_list(struct dentry *dentry, struct ptlrpc_request *req, } static -int mds_pack_posix_acl(struct lustre_msg *repmsg, int offset, +int mds_pack_posix_acl(struct lustre_msg *repmsg, int *offset, struct mds_body *body, struct inode *inode) { struct dentry de = { .d_inode = inode }; __u32 buflen, *sizep; void *buf; - int size; + int size, pack_off = *offset; ENTRY; + sizep = lustre_msg_buf(repmsg, pack_off++, 4); + if (!sizep) { + CERROR("can't locate returned acl size buf\n"); + RETURN(-EPROTO); + } + if (!inode->i_op->getxattr) RETURN(0); - buflen = repmsg->buflens[offset + 1]; - buf = lustre_msg_buf(repmsg, offset + 1, buflen); + buflen = repmsg->buflens[pack_off]; + buf = lustre_msg_buf(repmsg, pack_off++, buflen); size = inode->i_op->getxattr(&de, XATTR_NAME_ACL_ACCESS, buf, buflen); if (size == -ENODATA || size == -EOPNOTSUPP) @@ -1080,25 +1087,20 @@ int mds_pack_posix_acl(struct lustre_msg *repmsg, int offset, if (size < 0) RETURN(size); LASSERT(size); - - sizep = lustre_msg_buf(repmsg, offset, 4); - if (!sizep) { - CERROR("can't locate returned acl size buf\n"); - RETURN(-EPROTO); - } - - *sizep = cpu_to_le32(size); body->valid |= OBD_MD_FLACL; + *sizep = cpu_to_le32(size); + + *offset = pack_off; RETURN(0); } -static -int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off, +int mds_pack_remote_perm(struct ptlrpc_request *req, int *reply_off, struct mds_body *body, struct inode *inode) { struct lustre_sec_desc *lsd; struct mds_remote_perm *perm; + int pack_off = *reply_off; __u32 lsd_perms; LASSERT(inode->i_op); @@ -1106,7 +1108,7 @@ int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off, LASSERT(req->rq_export->exp_mds_data.med_remote); perm = (struct mds_remote_perm *) - lustre_msg_buf(req->rq_repmsg, reply_off, sizeof(perm)); + lustre_msg_buf(req->rq_repmsg, pack_off++, sizeof(perm)); if (!perm) return -EINVAL; @@ -1143,11 +1145,13 @@ int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off, perm->mrp_perm |= MAY_READ; body->valid |= (OBD_MD_FLACL | OBD_MD_FLRMTACL); + + *reply_off = pack_off; RETURN(0); } -int mds_pack_acl(struct ptlrpc_request *req, int reply_off, +int mds_pack_acl(struct ptlrpc_request *req, int *reply_off, struct mds_body *body, struct inode *inode) { int rc; @@ -1168,7 +1172,7 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry, struct mds_export_data *med = &req->rq_export->u.eu_mds_data; struct inode *inode = dentry->d_inode; struct mds_body *body; - int rc = 0; + int rc = 0, offset = 0; ENTRY; if (inode == NULL && !(dentry->d_flags & DCACHE_CROSS_REF)) @@ -1212,10 +1216,15 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry, rc = mds_pack_xattr_list(dentry, req, body, reply_off); } + offset = reply_off + ((reqbody->valid & OBD_MD_FLEASIZE) ? 2 : 1); if (reqbody->valid & OBD_MD_FLACL) { - int inc = (reqbody->valid & OBD_MD_FLEASIZE) ? 2 : 1; - rc = mds_pack_acl(req, reply_off + inc, body, inode); - } + rc = mds_pack_acl(req, &offset, body, inode); + } + + if (reqbody->valid & OBD_MD_FLKEY) { + rc = mds_pack_gskey(obd, req->rq_repmsg, &offset, + body, inode); + } if (rc == 0) mds_body_do_reverse_map(med, body); @@ -1333,11 +1342,16 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct dentry *de, if (req->rq_export->exp_mds_data.med_remote) { size[bufcount++] = sizeof(struct mds_remote_perm); } else { - size[bufcount++] = 4; + size[bufcount++] = sizeof(int); size[bufcount++] = xattr_acl_size(LL_ACL_MAX_ENTRIES); } } + if (body->valid & OBD_MD_FLKEY) { + size[bufcount++] = sizeof(int); + size[bufcount++] = sizeof(struct crypto_key); + } + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { CERROR("failed MDS_GETATTR_PACK test\n"); req->rq_status = -ENOMEM; @@ -1699,7 +1713,6 @@ out_pop: mds_exit_ucred(&uc); return rc; } - static int mds_access_check(struct ptlrpc_request *req, int offset) { struct obd_device *obd = req->rq_export->exp_obd; @@ -1710,7 +1723,7 @@ static int mds_access_check(struct ptlrpc_request *req, int offset) struct lvfs_ucred uc; int rep_size[2] = {sizeof(*body), sizeof(struct mds_remote_perm)}; - int rc = 0; + int rc = 0, rep_offset; ENTRY; if (!req->rq_export->exp_mds_data.med_remote) { @@ -1756,7 +1769,9 @@ static int mds_access_check(struct ptlrpc_request *req, int offset) body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body)); LASSERT(body); - rc = mds_pack_remote_perm(req, 1, body, de->d_inode); + rep_offset = 1; + rc = mds_pack_remote_perm(req, &rep_offset, body, de->d_inode); + EXIT; out_dput: @@ -2689,6 +2704,12 @@ static int mds_set_info(struct obd_export *exp, __u32 keylen, "mds_conn", valsize, &group); RETURN(rc); } + if (keylen >= strlen("crypto_type") && + memcmp(key, "crypto_type", keylen) == 0) { + rc = mds_set_crypto_type(obd, val, vallen); + RETURN(rc); + } + CDEBUG(D_IOCTL, "invalid key\n"); RETURN(-EINVAL); } @@ -2707,8 +2728,10 @@ static int mdt_set_info(struct ptlrpc_request *req) } keylen = req->rq_reqmsg->buflens[0]; - if (keylen == strlen("mds_type") && - memcmp(key, "mds_type", keylen) == 0) { + if ((keylen == strlen("mds_type") && + memcmp(key, "mds_type", keylen) == 0) || + (keylen == strlen("crypto_type") && + memcmp(key, "crypto_type", keylen) == 0)) { rc = lustre_pack_reply(req, 0, NULL, NULL); if (rc) RETURN(rc); @@ -3624,7 +3647,9 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, "mds_ldlm_client", &obd->obd_ldlm_client); obd->obd_replayable = 1; - + + mds->mds_crypto_type = NO_CRYPTO; + rc = mds_postsetup(obd); if (rc) GOTO(err_fs, rc); @@ -4021,6 +4046,37 @@ void intent_set_disposition(struct ldlm_reply *rep, int flag) rep->lock_policy_res1 |= flag; } +static int mds_intent_prepare_reply_buffers(struct ptlrpc_request *req, + struct ldlm_intent *it) +{ + struct mds_obd *mds = &req->rq_export->exp_obd->u.mds; + int rc, reply_buffers; + int repsize[5] = {sizeof(struct ldlm_reply), + sizeof(struct mds_body), + mds->mds_max_mdsize}; + ENTRY; + + reply_buffers = 3; + if (it->opc & ( IT_OPEN | IT_GETATTR | IT_LOOKUP | IT_CHDIR )) { + if (req->rq_export->exp_mds_data.med_remote) { + repsize[reply_buffers++] = + sizeof(struct mds_remote_perm); + } else { + repsize[reply_buffers++] = sizeof(int); + repsize[reply_buffers++] = + xattr_acl_size(LL_ACL_MAX_ENTRIES); + } + /*FIXME: ugly here, should be optimize for there + * is no crypto key*/ + repsize[reply_buffers++] = sizeof(int); + repsize[reply_buffers++] = sizeof(struct crypto_key); + } + + rc = lustre_pack_reply(req, reply_buffers, repsize, NULL); + + RETURN(rc); +} + static int mds_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp, void *req_cookie, ldlm_mode_t mode, int flags, void *data) @@ -4028,15 +4084,11 @@ static int mds_intent_policy(struct ldlm_namespace *ns, struct ptlrpc_request *req = req_cookie; struct ldlm_lock *lock = *lockp; struct ldlm_intent *it; - struct mds_obd *mds = &req->rq_export->exp_obd->u.mds; struct ldlm_reply *rep; struct lustre_handle lockh[2] = {{0}, {0}}; struct ldlm_lock *new_lock = NULL; int getattr_part = MDS_INODELOCK_UPDATE; - int rc, reply_buffers; - int repsize[5] = {sizeof(struct ldlm_reply), - sizeof(struct mds_body), - mds->mds_max_mdsize}; + int rc; int offset = MDS_REQ_INTENT_REC_OFF; ENTRY; @@ -4061,19 +4113,8 @@ static int mds_intent_policy(struct ldlm_namespace *ns, LDLM_DEBUG(lock, "intent policy, opc: %s", ldlm_it2str(it->opc)); - reply_buffers = 3; - if (it->opc & ( IT_OPEN | IT_GETATTR | IT_LOOKUP | IT_CHDIR )) { - if (req->rq_export->exp_mds_data.med_remote) { - reply_buffers = 4; - repsize[3] = sizeof(struct mds_remote_perm); - } else { - reply_buffers = 5; - repsize[3] = 4; - repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES); - } - } + rc = mds_intent_prepare_reply_buffers(req, it); - rc = lustre_pack_reply(req, reply_buffers, repsize, NULL); if (rc) RETURN(req->rq_status = rc); diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index 535ff71..79c01d7 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -133,6 +133,12 @@ int mds_init_ucred(struct lvfs_ucred *ucred, struct ptlrpc_request *req, struct mds_req_sec_desc *rsd); void mds_exit_ucred(struct lvfs_ucred *ucred); +int mds_set_gskey(struct obd_device *obd, void *handle, + struct inode *inode, void *key, int key_len, int valid); +int mds_set_crypto_type(struct obd_device *obd, void *val, __u32 vallen); + +int mds_pack_gskey(struct obd_device *obd, struct lustre_msg *repmsg, + int *offset, struct mds_body *body, struct inode *inode); /* mds/mds_unlink_open.c */ int mds_cleanup_orphans(struct obd_device *obd); @@ -259,8 +265,9 @@ int mds_pack_xattr(struct dentry *dentry, struct ptlrpc_request *req, struct mds_body *repbody, int req_off, int reply_off); int mds_pack_xattr_list(struct dentry *dentry, struct ptlrpc_request *req, struct mds_body *repbody, int reply_off); -int mds_pack_acl(struct ptlrpc_request *req, int reply_off, +int mds_pack_acl(struct ptlrpc_request *req, int *reply_off, struct mds_body *body, struct inode *inode); + int mds_pack_inode2id(struct obd_device *, struct lustre_id *, struct inode *, int); @@ -272,6 +279,7 @@ void mds_pack_dentry2id(struct obd_device *, struct lustre_id *, void mds_pack_dentry2body(struct obd_device *, struct mds_body *b, struct dentry *, int); + #endif /* mds/mds_lmv.c */ diff --git a/lustre/mds/mds_lib.c b/lustre/mds/mds_lib.c index eb3231b..b92cbe0 100644 --- a/lustre/mds/mds_lib.c +++ b/lustre/mds/mds_lib.c @@ -44,11 +44,14 @@ #include #include #include +#include #include #include #include #include +#include +#include #include "mds_internal.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) @@ -214,6 +217,132 @@ int mds_pack_inode2id(struct obd_device *obd, RETURN(rc); } +int mds_pack_gskey(struct obd_device *obd, struct lustre_msg *repmsg, + int *offset, struct mds_body *body, struct inode *inode) +{ + struct mds_obd *mds = &obd->u.mds; + struct crypto_key_md *md_key; + struct crypto_key *ckey; + __u32 buflen, *sizep; + void *buf; + int size, rc = 0; + ENTRY; + + if ((mds->mds_crypto_type != MKS_TYPE && + mds->mds_crypto_type != GKS_TYPE)) + RETURN(rc); + + sizep = lustre_msg_buf(repmsg, (*offset)++, 4); + if (!sizep) { + CERROR("can't locate returned ckey size buf\n"); + RETURN(-EPROTO); + } + *sizep = cpu_to_le32(sizeof(*ckey)); + + OBD_ALLOC(md_key, sizeof(*md_key)); + + buflen = repmsg->buflens[*offset]; + buf = lustre_msg_buf(repmsg, (*offset)++, buflen); + + size = fsfilt_get_md(obd, inode, md_key, sizeof(*md_key), + EA_KEY); + if (size < 0) { + CERROR("Can not get gskey from MDS ino %lu rc %d\n", + inode->i_ino, size); + GOTO(out, rc = size); + } + if (le32_to_cpu(md_key->md_magic) != MD_KEY_MAGIC) { + CDEBUG(D_INFO, "given match %x != magic %x\n", + md_key->md_magic, MD_KEY_MAGIC); + GOTO(out, rc = 0); + } + + CDEBUG(D_INFO, "get key %s mac %s for ino %lu size %d \n", + md_key->md_ck.ck_key, md_key->md_ck.ck_mac, inode->i_ino, size); + ckey=(struct crypto_key*)buf; + + memcpy(ckey, &md_key->md_ck, sizeof(*ckey)); + body->valid |= OBD_MD_FLKEY; +out: + OBD_FREE(md_key, sizeof(*md_key)); + RETURN(rc); +} + +static int mds_get_gskey(struct inode *inode, struct crypto_key *ckey) +{ + LASSERT(ckey); + /*tmp create gs key here*/ + get_random_bytes(ckey->ck_key, KEY_SIZE); + ckey->ck_type = MKS_TYPE; + RETURN(0); +} + +int mds_set_gskey(struct obd_device *obd, void *handle, + struct inode *inode, void *key, int key_len, + int valid) +{ + struct crypto_key_md *md_key = NULL; + struct crypto_key *ckey = (struct crypto_key *)key; + struct mds_obd *mds = &obd->u.mds; + int rc = 0; + ENTRY; + + if ((mds->mds_crypto_type != MKS_TYPE && + mds->mds_crypto_type != GKS_TYPE) || key_len == 0) + RETURN(rc); + + OBD_ALLOC(md_key, sizeof(*md_key)); + LASSERT(ckey != NULL); + if (mds->mds_crypto_type == MKS_TYPE) { + mds_get_gskey(inode, ckey); + } + rc = fsfilt_get_md(obd, inode, md_key, sizeof(*md_key), + EA_KEY); + if (rc < 0) + GOTO(free, rc); + LASSERT(le32_to_cpu(md_key->md_magic) == MD_KEY_MAGIC || + md_key->md_magic == 0); + if (le32_to_cpu(md_key->md_magic) == MD_KEY_MAGIC) { + CDEBUG(D_INFO, "reset key %s mac %s", md_key->md_ck.ck_mac, + md_key->md_ck.ck_key); + } + + md_key->md_magic = cpu_to_le32(MD_KEY_MAGIC); + if (valid & ATTR_MAC) { + memcpy(md_key->md_ck.ck_mac, ckey->ck_mac, MAC_SIZE); + CDEBUG(D_INFO, "set mac %s for ino %lu \n", + md_key->md_ck.ck_mac, inode->i_ino); + } + if (valid & ATTR_KEY) { + memcpy(md_key->md_ck.ck_key, ckey->ck_key, KEY_SIZE); + CDEBUG(D_INFO, "set key %s for ino %lu \n", + md_key->md_ck.ck_key, inode->i_ino); + } + rc = fsfilt_set_md(obd, inode, handle, md_key, + sizeof(*md_key), EA_KEY); +free: + if (md_key) + OBD_FREE(md_key, sizeof(*md_key)); + RETURN(rc); +} + +int mds_set_crypto_type(struct obd_device *obd, void *val, __u32 vallen) +{ + struct mds_obd *mds = &obd->u.mds; + ENTRY; + + if (vallen >= strlen("mks") && + memcmp(val, "mks", vallen) == 0) { + mds->mds_crypto_type = MKS_TYPE; + } + if (vallen >= strlen("gks") && + memcmp(val, "gks", vallen) == 0) { + mds->mds_crypto_type = GKS_TYPE; + } + + CDEBUG(D_IOCTL, "invalid key\n"); + RETURN(0); +} /* Note that we can copy all of the fields, just some will not be "valid" */ void mds_pack_inode2body(struct obd_device *obd, struct mds_body *b, struct inode *inode, int fid) @@ -252,6 +381,7 @@ void mds_pack_inode2body(struct obd_device *obd, struct mds_body *b, b->valid |= OBD_MD_FID; mds_pack_inode2id(obd, &b->id1, inode, fid); + } /* unpacking */ @@ -295,6 +425,14 @@ static int mds_setattr_unpack(struct ptlrpc_request *req, int offset, r->ur_ea2datalen = req->rq_reqmsg->buflens[offset + 2]; } + if (req->rq_reqmsg->bufcount > offset + 3) { + r->ur_ea3data = lustre_msg_buf(req->rq_reqmsg, offset + 3, 0); + if (r->ur_ea3data == NULL) + RETURN (-EFAULT); + + r->ur_ea3datalen = req->rq_reqmsg->buflens[offset + 3]; + } + RETURN(0); } @@ -446,7 +584,7 @@ static int mds_open_unpack(struct ptlrpc_request *req, int offset, r->ur_rdev = rec->cr_rdev; r->ur_time = rec->cr_time; r->ur_flags = rec->cr_flags; - + LASSERT_REQSWAB (req, offset + 1); r->ur_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0); if (r->ur_name == NULL) @@ -454,12 +592,19 @@ static int mds_open_unpack(struct ptlrpc_request *req, int offset, r->ur_namelen = req->rq_reqmsg->buflens[offset + 1]; LASSERT_REQSWAB (req, offset + 2); - if (req->rq_reqmsg->bufcount > offset + 2) { + + if (req->rq_reqmsg->bufcount > offset + 2) { r->ur_eadata = lustre_msg_buf(req->rq_reqmsg, offset + 2, 0); if (r->ur_eadata == NULL) RETURN(-EFAULT); r->ur_eadatalen = req->rq_reqmsg->buflens[offset + 2]; } + + if (rec->cr_flags & MDS_OPEN_HAS_KEY) { + LASSERT(req->rq_reqmsg->bufcount > offset + 3); + r->ur_ea2data = lustre_msg_buf(req->rq_reqmsg, offset + 3, 0); + r->ur_ea2datalen = req->rq_reqmsg->buflens[offset + 3]; + } RETURN(0); } diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 42a6e12..baba9d1 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "mds_internal.h" @@ -700,7 +701,7 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild, struct mds_file_data *mfd = NULL; obd_id *ids = NULL; unsigned mode; - int rc = 0; + int rc = 0, reply_off; ENTRY; /* atomically create objects if necessary */ @@ -748,13 +749,23 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild, } } } - rc = mds_pack_acl(req, 3, body, dchild->d_inode); + + reply_off = 3; + rc = mds_pack_acl(req, &reply_off, body, dchild->d_inode); + if (rc < 0) { CERROR("pack posix acl: rc = %d\n", rc); up(&dchild->d_inode->i_sem); RETURN(rc); } + rc = mds_pack_gskey(obd, req->rq_repmsg, &reply_off, body, + dchild->d_inode); + if (rc < 0) { + CERROR("mds_pack_gskey: rc = %d\n", rc); + up(&dchild->d_inode->i_sem); + RETURN(rc); + } /* If the inode has no EA data, then MDSs hold size, mtime */ if (S_ISREG(dchild->d_inode->i_mode) && !(body->valid & OBD_MD_FLEASIZE)) { @@ -1202,7 +1213,16 @@ got_child: else { MD_COUNTER_INCREMENT(obd, create); } - + + if ((rec->ur_flags & MDS_OPEN_HAS_KEY) || + mds->mds_crypto_type == MKS_TYPE) { + rc = mds_set_gskey(obd, handle, dchild->d_inode, + rec->ur_ea2data, rec->ur_ea2datalen, + ATTR_KEY | ATTR_MAC); + if (rc) { + CERROR("error in set gs key rc %d\n", rc); + } + } if (ino) { rc = mds_update_inode_sid(obd, dchild->d_inode, handle, rec->ur_id2); @@ -1888,6 +1908,7 @@ int mds_close(struct ptlrpc_request *req, int offset) RETURN(0); } + int mds_done_writing(struct ptlrpc_request *req, int offset) { struct mds_body *body; diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 51c1a24..dee71d8 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -472,6 +472,7 @@ static int mds_get_md_type(char *name) RETURN(EA_SID); RETURN(0); } + /* In the raw-setattr case, we lock the child inode. * In the write-back case or if being called from open, the client holds a lock * already. @@ -589,10 +590,9 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset, flags); } else if (rec->ur_iattr.ia_valid & ATTR_EA_RM) { rc = -EOPNOTSUPP; - if (!med->med_remote && inode->i_op && - inode->i_op->removexattr) - rc = inode->i_op->removexattr( - de, rec->ur_eadata); + if (inode->i_op && inode->i_op->removexattr) + rc = inode->i_op->removexattr(de, + rec->ur_eadata); } else if (rec->ur_iattr.ia_valid & ATTR_EA_CMOBD) { char *name; int type; @@ -608,7 +608,9 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset, rec->ur_ea2datalen, type); if (rc) GOTO(cleanup, rc); - } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) { + } else if ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) && + !((rec->ur_iattr.ia_valid & ATTR_KEY) || + (rec->ur_iattr.ia_valid & ATTR_MAC))) { struct lov_stripe_md *lsm = NULL; struct lov_user_md *lum = NULL; @@ -640,7 +642,19 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset, GOTO(cleanup, rc); } } - } + } + if ((rec->ur_iattr.ia_valid & ATTR_KEY) || + (rec->ur_iattr.ia_valid & ATTR_MAC)) { + void *key; + int keylen; + LASSERT(rec->ur_eadatalen || rec->ur_ea3datalen); + LASSERT(rec->ur_eadata || rec->ur_ea3data); + key = rec->ur_eadata ? rec->ur_eadata : rec->ur_ea3data; + keylen = rec->ur_eadatalen ? rec->ur_eadatalen : + rec->ur_ea3datalen; + mds_set_gskey(obd, handle, inode, key, keylen, + rec->ur_iattr.ia_valid); + } } body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body)); @@ -905,6 +919,14 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, if (IS_ERR(handle)) GOTO(cleanup, rc = PTR_ERR(handle)); rc = ll_vfs_create(dir, dchild, rec->ur_mode, NULL); + if (rec->ur_eadata && rec->ur_eadatalen && + (rc == 0) && (dchild->d_inode != NULL)) { + /*Assumption: When ur_eadata is not NULL, + *ur_eadata is crypto key, should fix it later, Wangdi*/ + mds_set_gskey(obd, handle, dchild->d_inode, + rec->ur_eadata, rec->ur_eadatalen, + ATTR_MAC | ATTR_KEY); + } EXIT; break; } diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index d5f59ec..0d825c7 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -423,7 +423,8 @@ struct lustre_profile *class_get_profile(char * prof) int class_add_profile(int proflen, char *prof, int lovlen, char *lov, - int lmvlen, char *lmv) + int lmvlen, char *lmv, + int gkclen, char *gkc) { struct lustre_profile *lprof; int err = 0; @@ -452,9 +453,15 @@ int class_add_profile(int proflen, char *prof, GOTO(out, err = -ENOMEM); memcpy(lprof->lp_lmv, lmv, lmvlen); } - + if (gkclen > 0 ) { + LASSERT(gkclen == (strlen(gkc) + 1)); + OBD_ALLOC(lprof->lp_gkc, gkclen); + if (lprof->lp_gkc == NULL) + GOTO(out, err = -ENOMEM); + memcpy(lprof->lp_gkc, gkc, gkclen); + } + list_add(&lprof->lp_list, &lustre_profile_list); - out: RETURN(err); } @@ -510,10 +517,11 @@ int class_process_config(struct lustre_cfg *lcfg) GOTO(out, err); } case LCFG_MOUNTOPT: { - CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n", + CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s gkc %s \n", lustre_cfg_string(lcfg, 1), lustre_cfg_string(lcfg, 2), - lustre_cfg_string(lcfg, 3)); + lustre_cfg_string(lcfg, 3), + lustre_cfg_string(lcfg, 4)); /* set these mount options somewhere, so ll_fill_super * can find them. */ err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1), @@ -521,7 +529,9 @@ int class_process_config(struct lustre_cfg *lcfg) LUSTRE_CFG_BUFLEN(lcfg, 2), lustre_cfg_string(lcfg, 2), LUSTRE_CFG_BUFLEN(lcfg, 3), - lustre_cfg_string(lcfg, 3)); + lustre_cfg_string(lcfg, 3), + LUSTRE_CFG_BUFLEN(lcfg, 4), + lustre_cfg_string(lcfg, 4)); GOTO(out, err); } case LCFG_DEL_MOUNTOPT: { diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 42f4736..1b13258 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2180,6 +2180,8 @@ int filter_setattr(struct obd_export *exp, struct obdo *oa, struct filter_obd *filter; struct ldlm_resource *res; struct dentry *dentry; + obd_uid uid; + obd_gid gid; int rc; ENTRY; @@ -2188,7 +2190,6 @@ int filter_setattr(struct obd_export *exp, struct obdo *oa, filter = &exp->exp_obd->u.filter; push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL); - /* make sure that object is allocated. */ dentry = filter_crow_object(exp->exp_obd, oa); if (IS_ERR(dentry)) @@ -2434,7 +2435,6 @@ filter_crow_object(struct obd_device *obd, struct obdo *oa) RETURN(dentry); f_dput(dentry); - CDEBUG(D_INODE, "OSS object "LPU64"/"LPU64 " does not exists - allocate it now\n", oa->o_id, oa->o_gr); diff --git a/lustre/obdfilter/filter_io.c b/lustre/obdfilter/filter_io.c index 643a427..3d505ec 100644 --- a/lustre/obdfilter/filter_io.c +++ b/lustre/obdfilter/filter_io.c @@ -506,6 +506,8 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa, struct fsfilt_objinfo fso; struct obd_device *obd; obd_size left; + obd_uid uid; + obd_gid gid; void *iobuf; ENTRY; @@ -522,6 +524,9 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa, obd = exp->exp_obd; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); + uid = oa->o_valid & OBD_MD_FLUID ? oa->o_uid : 0; + gid = oa->o_valid & OBD_MD_FLGID ? oa->o_gid : 0; + /* make sure that object is already allocated */ dentry = filter_crow_object(obd, oa); if (IS_ERR(dentry)) diff --git a/lustre/osc/osc_create.c b/lustre/osc/osc_create.c index 4202edc..7596682 100644 --- a/lustre/osc/osc_create.c +++ b/lustre/osc/osc_create.c @@ -128,6 +128,49 @@ int osc_create(struct obd_export *exp, struct obdo *oa, spin_unlock(&oscc->oscc_lock); RETURN(rc); } + while (try_again) { + /* If orphans are being recovered, then we must wait until + it is finished before we can continue with create. */ + if (oscc_recovering(oscc)) { + struct l_wait_info lwi; + + CDEBUG(D_HA,"%p: oscc recovery in progress, waiting\n", + oscc); + + lwi = LWI_TIMEOUT(MAX(obd_timeout*HZ/4, 1), NULL, NULL); + rc = l_wait_event(oscc->oscc_waitq, + !oscc_recovering(oscc), &lwi); + LASSERT(rc == 0 || rc == -ETIMEDOUT); + if (rc == -ETIMEDOUT) { + CDEBUG(D_ERROR,"%p: timeout waiting on recovery\n", + oscc); + RETURN(rc); + } + CDEBUG(D_HA, "%p: oscc recovery over, waking up\n", + oscc); + } + + spin_lock(&oscc->oscc_lock); + if (oscc->oscc_flags & OSCC_FLAG_EXITING) { + spin_unlock(&oscc->oscc_lock); + break; + } + + if (oscc->oscc_flags & OSCC_FLAG_NOSPC) { + rc = -ENOSPC; + spin_unlock(&oscc->oscc_lock); + break; + } + + oscc->oscc_next_id++; + oa->o_id = oscc->oscc_next_id; + try_again = 0; + spin_unlock(&oscc->oscc_lock); + + CDEBUG(D_HA, "%s: returning objid "LPU64"\n", + oscc->oscc_obd->u.cli.cl_import->imp_target_uuid.uuid, + oa->o_id); + } while (try_again) { /* If orphans are being recovered, then we must wait until diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 9dc9d44..12fd279 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -63,6 +63,7 @@ #include #include #include +#include #include "osc_internal.h" /* Pack OSC object metadata for disk storage (LE byte order). */ @@ -730,6 +731,28 @@ static obd_count cksum_pages(int nob, obd_count page_count, } #endif +#define osc_encrypt_page(page, off, count) \ + osc_crypt_page(page, off, count, ENCRYPT_DATA) +#define osc_decrypt_page(page, off, count) \ + osc_crypt_page(page, off, count, DECRYPT_DATA) + +/*Put a global call back var here is Ugly, but put it to client_obd + *also seems not a good idea, WangDi*/ +crypt_cb_t osc_crypt_cb = NULL; + +static int osc_crypt_page(struct page *page, obd_off page_off, obd_off count, + int flags) +{ + int rc = 0; + ENTRY; + + if (osc_crypt_cb != NULL) + rc = osc_crypt_cb(page, page_off, count, flags); + if (rc != 0) + CERROR("crypt page error %d \n", rc); + RETURN(rc); +} + static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa, struct lov_stripe_md *lsm, obd_count page_count, struct brw_page *pga, int *requested_nobp, @@ -798,6 +821,10 @@ static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa, pg->pg, pg->pg->private, pg->pg->index, pg->disk_offset, pg_prev->pg, pg_prev->pg->private, pg_prev->pg->index, pg_prev->disk_offset); + + if (opc == OST_WRITE) { + osc_encrypt_page(pg->pg, pg->page_offset, pg->count); + } ptlrpc_prep_bulk_page(desc, pg->pg, pg->page_offset & ~PAGE_MASK, pg->count); @@ -868,7 +895,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa, RETURN(-EPROTO); } LASSERT (req->rq_bulk->bd_nob == requested_nob); - + osc_decrypt_page(pga->pg, pga->page_offset, + pga->count); RETURN(check_write_rcs(req, requested_nob, niocount, page_count, pga)); } @@ -919,6 +947,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa, req->rq_import->imp_connection->c_peer.peer_id.nid); } #endif + osc_decrypt_page(pga->pg, pga->page_offset, pga->count); RETURN(0); } @@ -2949,6 +2978,12 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen, ptlrpcs_import_flush_current_creds(cli->cl_import); RETURN(0); } + if (keylen == strlen("crypto_cb") && + memcmp(key, "crypto_cb", keylen) == 0) { + LASSERT(vallen == sizeof(crypt_cb_t)); + osc_crypt_cb = (crypt_cb_t)val; + RETURN(0); + } if (keylen < strlen("mds_conn") || memcmp(key, "mds_conn", keylen) != 0) diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c index 78c79b4..6ede5d6 100644 --- a/lustre/ptlrpc/import.c +++ b/lustre/ptlrpc/import.c @@ -746,6 +746,7 @@ int ptlrpc_disconnect_import(struct obd_import *imp) case OST_CONNECT: rq_opc = OST_DISCONNECT; break; case MDS_CONNECT: rq_opc = MDS_DISCONNECT; break; case MGMT_CONNECT: rq_opc = MGMT_DISCONNECT; break; + case GKS_CONNECT: rq_opc = GKS_DISCONNECT; break; default: CERROR("don't know how to disconnect from %s (connect_op %d)\n", imp->imp_target_uuid.uuid, imp->imp_connect_op); diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 99b667b..5db619a 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -35,6 +35,7 @@ #include #include #include +#include #define HDR_SIZE(count) \ @@ -481,9 +482,25 @@ void *mdc_create_pack(struct lustre_msg *msg, int offset, return ((void*)tmp + size_round(datalen)); } +__u32 mds_pack_open_flags(__u32 flags) +{ + return + (flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC | + MDS_OPEN_DELAY_CREATE | MDS_OPEN_HAS_EA | + MDS_OPEN_HAS_OBJS)) | + ((flags & O_CREAT) ? MDS_OPEN_CREAT : 0) | + ((flags & O_EXCL) ? MDS_OPEN_EXCL : 0) | + ((flags & O_TRUNC) ? MDS_OPEN_TRUNC : 0) | + ((flags & O_APPEND) ? MDS_OPEN_APPEND : 0) | + ((flags & O_SYNC) ? MDS_OPEN_SYNC : 0) | + ((flags & O_DIRECTORY) ? MDS_OPEN_DIRECTORY : 0) | + 0; +} + void *mdc_setattr_pack(struct lustre_msg *msg, int offset, struct mdc_op_data *data, struct iattr *iattr, - void *ea, int ealen, void *ea2, int ea2len) + void *ea, int ealen, void *ea2, int ea2len, + void *ea3, int ea3len) { struct mds_rec_setattr *rec = lustre_msg_buf(msg, offset, sizeof(*rec)); char *tmp = NULL; @@ -515,6 +532,13 @@ void *mdc_setattr_pack(struct lustre_msg *msg, int offset, memcpy(lustre_msg_buf(msg, offset + 2, ea2len), ea2, ea2len); tmp += size_round(ea2len); + + if (ea3len == 0) + return (void*)tmp; + + memcpy(lustre_msg_buf(msg, offset + 3, ea3len), ea3, ea3len); + tmp += size_round(ea3len); + return (void*)tmp; } @@ -883,4 +907,23 @@ int llog_log_swabbed(struct llog_log_hdr *hdr) void lustre_assert_wire_constants(void) { } - +/* for gks key rec */ +void lustre_swab_key_perms(struct key_perm *kperm) +{ + int i; + __swab32s(&kperm->kp_uid); + __swab32s(&kperm->kp_gid); + __swab32s(&kperm->kp_mode); + __swab32s(&kperm->kp_acl_count); + for (i = 0; i < kperm->kp_acl_count; i++) { + __swab16s(&kperm->kp_acls[i].e_tag); + __swab16s(&kperm->kp_acls[i].e_perm); + __swab32s(&kperm->kp_acls[i].e_id); + } +} +void lustre_swab_key_context (struct key_context *kctxt) +{ + __swab32s (&kctxt->kc_command); + __swab32s (&kctxt->kc_valid); /* for use with open */ + lustre_swab_key_perms(&kctxt->kc_perm); +} diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c index dac116b..d2056ac 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -196,11 +196,14 @@ EXPORT_SYMBOL(lustre_swab_ldlm_reply); EXPORT_SYMBOL(lustre_swab_ptlbd_op); EXPORT_SYMBOL(lustre_swab_ptlbd_niob); EXPORT_SYMBOL(lustre_swab_ptlbd_rsp); +EXPORT_SYMBOL(lustre_swab_key_context); +EXPORT_SYMBOL(lustre_swab_key_perms); EXPORT_SYMBOL(mdc_create_pack); EXPORT_SYMBOL(mdc_setattr_pack); EXPORT_SYMBOL(mdc_unlink_pack); EXPORT_SYMBOL(mdc_link_pack); EXPORT_SYMBOL(mdc_rename_pack); +EXPORT_SYMBOL(mds_pack_open_flags); /* recover.c */ EXPORT_SYMBOL(ptlrpc_run_recovery_over_upcall); diff --git a/lustre/sec/Makefile.in b/lustre/sec/Makefile.in index 224d66b..172e651 100644 --- a/lustre/sec/Makefile.in +++ b/lustre/sec/Makefile.in @@ -1,6 +1,6 @@ MODULES := ptlrpcs ptlrpcs-objs := sec.o sec_null.o svcsec.o svcsec_null.o upcall_cache.o -@GSS_TRUE@subdir-m += gss +@GSS_TRUE@subdir-m += gss gks @INCLUDE_RULES@ diff --git a/lustre/sec/autoMakefile.am b/lustre/sec/autoMakefile.am index c14dbfe..740c33f 100644 --- a/lustre/sec/autoMakefile.am +++ b/lustre/sec/autoMakefile.am @@ -4,7 +4,7 @@ # See the file COPYING in this distribution if GSS -SUBDIRS = . gss #kcrypto +SUBDIRS = . gss gks #kcrypto endif if LIBLUSTRE diff --git a/lustre/sec/gks/Makefile.in b/lustre/sec/gks/Makefile.in new file mode 100644 index 0000000..cc439d0 --- /dev/null +++ b/lustre/sec/gks/Makefile.in @@ -0,0 +1,6 @@ +MODULES := gks gkc +gks-objs := lproc_gks.o gks_server.o +gkc-objs := lproc_gks.o gks_client.o +@INCLUDE_RULES@ + + diff --git a/lustre/sec/gks/Makefile.mk b/lustre/sec/gks/Makefile.mk new file mode 100644 index 0000000..9ce0737 --- /dev/null +++ b/lustre/sec/gks/Makefile.mk @@ -0,0 +1,11 @@ +# Copyright (C) 2004 Cluster File Systems, Inc. +# +# This code is issued under the GNU General Public License. +# See the file COPYING in this distribution + +include $(src)/../../portals/Kernelenv + +#obj-y += ptlrpcs_gss.o ptlrpcs_gss_krb5.o +obj-y += gks.o gkc.o +gks-objs := lprocfs_gks.o gks_server.o +gkc-objs := lprofs_gks.o gks_client.o diff --git a/lustre/sec/gks/autoMakefile.am b/lustre/sec/gks/autoMakefile.am new file mode 100644 index 0000000..b073b46 --- /dev/null +++ b/lustre/sec/gks/autoMakefile.am @@ -0,0 +1,13 @@ +# Copyright (C) 2004 Cluster File Systems, Inc. +# +# This code is issued under the GNU General Public License. +# See the file COPYING in this distribution + + +if MODULES +modulefs_DATA = gks$(KMODEXT) gkc$(KMODEXT) +endif + +DIST_SOURCES = gks_client.c gks_server.c lproc_gks.c gks_internal.h +MOSTLYCLEANFILES := @MOSTLYCLEANFILES@ + diff --git a/lustre/sec/gks/gks_client.c b/lustre/sec/gks/gks_client.c new file mode 100644 index 0000000..161f938 --- /dev/null +++ b/lustre/sec/gks/gks_client.c @@ -0,0 +1,201 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * lustre GS client + * Copyright (c) 2001-2003 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef EXPORT_SYMTAB +# define EXPORT_SYMTAB +#endif +#define DEBUG_SUBSYSTEM S_GSS + +#include +#include +#include +#include + +#include "gks_internal.h" + +static int gkc_get_key(struct obd_export *exp, struct key_parms *kparms, + struct crypto_key *ckey, int op) +{ + struct ptlrpc_request *req; + struct crypto_key *rep_key; + int rc, bufcount = 1, size[3] = {0, 0, 0}; + void *buf; + ENTRY; + + size[0] = lustre_secdesc_size(); + + size[bufcount++] = kparms->context_size; + if (kparms->perm && kparms->perm_size > 0) { + size[bufcount++] = kparms->perm_size; + } + req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_GKS_VERSION, + op, bufcount, size, NULL); + if (req == NULL) + RETURN(-ENOMEM); + + lustre_pack_secdesc(req, size[0]); + + buf = lustre_msg_buf(req->rq_reqmsg, 1, kparms->context_size); + memcpy(buf, kparms->context, kparms->context_size); + + if (kparms->perm && kparms->perm_size) { + buf = lustre_msg_buf(req->rq_reqmsg, 2, kparms->perm_size); + memcpy(buf, kparms->perm, kparms->perm_size); + } + + size[0] = sizeof(struct crypto_key); + req->rq_replen = lustre_msg_size(1, size); + + rc = ptlrpc_queue_wait(req); + + rep_key = lustre_msg_buf(req->rq_repmsg, 0, sizeof(struct crypto_key)); + + memcpy(ckey, rep_key, sizeof(*rep_key)); + + CDEBUG(D_INFO, "get enkey %s, mac %s\n", ckey->ck_key, ckey->ck_mac); + ptlrpc_req_finished(req); + + RETURN(rc); +} + +static int gkc_set_info(struct obd_export *exp, obd_count keylen, + void *key, obd_count vallen, void *val) +{ + int rc = -EINVAL; + if (keylen == strlen("async") && memcmp(key, "async", keylen) == 0) { + struct client_obd *cl = &exp->exp_obd->u.cli; + if (vallen != sizeof(int)) + RETURN(-EINVAL); + cl->cl_async = *(int *)val; + CDEBUG(D_HA, "%s: set async = %d\n", + exp->exp_obd->obd_name, cl->cl_async); + RETURN(0); + } + RETURN(rc); +} + +static int gkc_get_info(struct obd_export *exp, __u32 keylen, + void *key, __u32 *vallen, void *val) +{ + struct key_parms *kparms = (struct key_parms *)key; + struct crypto_key *ckey = (struct crypto_key *)val; + int rc = 0; + + ENTRY; + + LASSERT(*vallen == sizeof(*ckey)); + + switch (kparms->context->kc_command) { + case GKS_GET_KEY: + case GKS_DECRYPT_KEY: + case GKS_GET_MAC: + break; + default: + CERROR("Unknow op %d \n", kparms->context->kc_command); + rc = -EINVAL; + RETURN(rc); + } + rc = gkc_get_key(exp, kparms, ckey, kparms->context->kc_command); + RETURN(rc); +} +static int gkc_setup(struct obd_device *obd, obd_count len, void *buf) +{ + struct client_obd *cli = &obd->u.cli; + int rc; + ENTRY; + + OBD_ALLOC(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock)); + if (!cli->cl_rpc_lock) + RETURN(-ENOMEM); + gkc_init_rpc_lock(cli->cl_rpc_lock); + + ptlrpcd_addref(); + + rc = client_obd_setup(obd, len, buf); + if (rc) + GOTO(err_rpc_lock, rc); + + RETURN(rc); +err_rpc_lock: + OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock)); + ptlrpcd_decref(); + RETURN(rc); +} + +static int gkc_cleanup(struct obd_device *obd, int flags) +{ + struct client_obd *cli = &obd->u.cli; + + OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock)); + + ptlrpcd_decref(); + + return client_obd_cleanup(obd, 0); +} + +static int gkc_attach(struct obd_device *dev, obd_count len, void *data) +{ + struct lprocfs_static_vars lvars; + + lprocfs_init_vars(gkc, &lvars); + return lprocfs_obd_attach(dev, lvars.obd_vars); +} + +static int gkc_detach(struct obd_device *dev) +{ + return lprocfs_obd_detach(dev); +} + +static struct obd_ops gkc_obd_ops = { + .o_owner = THIS_MODULE, + .o_connect = client_connect_import, + .o_disconnect = client_disconnect_export, + .o_attach = gkc_attach, + .o_detach = gkc_detach, + .o_setup = gkc_setup, + .o_cleanup = gkc_cleanup, + .o_get_info = gkc_get_info, + .o_set_info = gkc_set_info, +}; + +static int __init gkc_init(void) +{ + struct lprocfs_static_vars lvars; + + lprocfs_init_vars(gkc, &lvars); + class_register_type(&gkc_obd_ops, NULL, lvars.module_vars, + LUSTRE_GKC_NAME); + return 0; +} + +static void gkc_exit(void) +{ + class_unregister_type(LUSTRE_GKC_NAME); +} + +MODULE_AUTHOR("Cluster File Systems, Inc. "); +MODULE_DESCRIPTION("Lustre GS Client (GS)"); +MODULE_LICENSE("GPL"); + +module_init(gkc_init); +module_exit(gkc_exit); + diff --git a/lustre/sec/gks/gks_internal.h b/lustre/sec/gks/gks_internal.h new file mode 100644 index 0000000..eae5dbc --- /dev/null +++ b/lustre/sec/gks/gks_internal.h @@ -0,0 +1,46 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ + +#ifndef _GKS_INTERNAL_H +#define _GKS_INTERNAL_H + +#define GKS_SERVICE_WATCHDOG_TIMEOUT 30000 +struct mdc_rpc_lock { + struct semaphore rpcl_sem; + struct lookup_intent *rpcl_it; +}; + +static inline void gkc_init_rpc_lock(struct mdc_rpc_lock *lck) +{ + sema_init(&lck->rpcl_sem, 1); + lck->rpcl_it = NULL; +} + +static inline void gkc_get_rpc_lock(struct mdc_rpc_lock *lck, + struct lookup_intent *it) +{ + ENTRY; + down(&lck->rpcl_sem); + if (it) { + lck->rpcl_it = it; + } +} + +static inline void gkc_put_rpc_lock(struct mdc_rpc_lock *lck, + struct lookup_intent *it) +{ + EXIT; + if (it == NULL) { + LASSERT(it == lck->rpcl_it); + up(&lck->rpcl_sem); + return; + } + if (it) { + LASSERT(it == lck->rpcl_it); + lck->rpcl_it = NULL; + up(&lck->rpcl_sem); + } +} + +#endif /* _GKS_INTERNAL_H */ diff --git a/lustre/sec/gks/gks_server.c b/lustre/sec/gks/gks_server.c new file mode 100644 index 0000000..1a9ec27 --- /dev/null +++ b/lustre/sec/gks/gks_server.c @@ -0,0 +1,503 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * lustre GS server + * Copyright (c) 2001-2003 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef EXPORT_SYMTAB +# define EXPORT_SYMTAB +#endif +#define DEBUG_SUBSYSTEM S_GKS + +#include +#include +#include +#include +#include +#include + +#include "gks_internal.h" + +#define GKS_KEY "19760218" +#define GKS_KEY_LEN 8 +#define GKS_MAC_ALG "sha1" +#define GKS_KEY_ALG "des" +#define GKS_KEY_ALG_MODE CRYPTO_TFM_MODE_CBC + +static int gks_cleanup(struct obd_device *obd, int flags) +{ + struct gks_obd *gks = &obd->u.gks; + ENTRY; + + if (gks->gks_mac_tfm) { + crypto_free_tfm(gks->gks_mac_tfm); + } + if (gks->gks_key.key) { + OBD_FREE(gks->gks_key.key, gks->gks_key.len); + } + if (gks->gks_key_tfm) { + crypto_free_tfm(gks->gks_key_tfm); + } + + RETURN(0); +} + +static int gks_setup(struct obd_device *obd, obd_count len, void *buf) +{ + struct gks_obd *gks = &obd->u.gks; + int rc = 0; + + gks->gks_mac_tfm = crypto_alloc_tfm(GKS_MAC_ALG, 0); + if (!gks->gks_mac_tfm) + RETURN(-ENOSYS); + /*Now: we only keep an unchanged key in the whole system*/ + gks->gks_key.len = GKS_KEY_LEN; + + OBD_ALLOC(gks->gks_key.key, GKS_KEY_LEN); + + LASSERT(gks->gks_key.key); + + memcpy(gks->gks_key.key, GKS_KEY, GKS_KEY_LEN); + /*set gks cipher type*/ + + gks->gks_key_tfm = crypto_alloc_tfm(GKS_KEY_ALG, GKS_KEY_ALG_MODE); + if (!gks->gks_key_tfm) + GOTO(out, rc = -ENOSYS); + if (crypto_cipher_setkey(gks->gks_key_tfm, gks->gks_key.key, + gks->gks_key.len)) + GOTO(out, rc = -ENOSYS); +out: + if (rc) { + gks_cleanup(obd, 0); + } + RETURN(rc); +} + +static int gks_connect(struct lustre_handle *conn, struct obd_device *obd, + struct obd_uuid *cluuid, struct obd_connect_data *data, + unsigned long flags) +{ + int rc; + ENTRY; + + if (!conn || !obd || !cluuid) + RETURN(-EINVAL); + + rc = class_connect(conn, obd, cluuid); + + RETURN(rc); +} + +static int gks_disconnect(struct obd_export *exp, unsigned long flags) +{ + int rc = 0; + ENTRY; + + rc = class_disconnect(exp, flags); + + target_destroy_export(exp); + + RETURN(rc); +} + +static int gks_msg_check_version(struct lustre_msg *msg) +{ + int rc = 0; + ENTRY; + + switch (msg->opc) { + case GKS_CONNECT: + case GKS_DISCONNECT: + rc = lustre_msg_check_version(msg, LUSTRE_OBD_VERSION); + if (rc) + CERROR("bad opc %u version %08x, expecting %08x\n", + msg->opc, msg->version, LUSTRE_OBD_VERSION); + break; + case GKS_GET_KEY: + case GKS_DECRYPT_KEY: + case GKS_GET_MAC: + rc = lustre_msg_check_version(msg, LUSTRE_GKS_VERSION); + if (rc) + CERROR("bad opc %u version %08x, expecting %08x\n", + msg->opc, msg->version, LUSTRE_GKS_VERSION); + break; + default: + CERROR("GKS unknown opcode %d\n", msg->opc); + rc = -ENOTSUPP; + break; + } + + RETURN(rc); +} + +static int crypto_get_gks_mac(struct ptlrpc_request *req, + struct key_perm *kperm, + __u8 *hmac) +{ + struct obd_device *obd = req->rq_export->exp_obd; + struct gks_obd *gks = &obd->u.gks; + int perm_size = crypto_kperm_size(kperm->kp_acl_count); + struct scatterlist sl = { + .page = virt_to_page(kperm), + .offset = (unsigned long)(kperm) % PAGE_SIZE, + .length = perm_size + }; + __u8 *key = gks->gks_key.key; + int keylen = gks->gks_key.len; + struct crypto_tfm *tfm = gks->gks_mac_tfm; + + ENTRY; + LASSERT(tfm); + + crypto_hmac(tfm, key, &keylen, &sl, 1, hmac); + + CDEBUG(D_INFO, "compute mac mac %s by uid %d gid %d" + "mode %d acl_count %d acl %p perm_size %d\n", + hmac, kperm->kp_uid, kperm->kp_gid, kperm->kp_mode, + kperm->kp_acl_count, kperm->kp_acls, perm_size); + + RETURN(0); +} +#define crypto_decrypt_gks_key(req, data, len) \ +crypto_crypt_gks_key(req, data, len, DECRYPT_DATA) + +#define crypto_encrypt_gks_key(req, data, len) \ +crypto_crypt_gks_key(req, data, len, ENCRYPT_DATA) + +static int crypto_crypt_gks_key(struct ptlrpc_request *req, + __u8 *data, int len, int mode) +{ + struct obd_device *obd = req->rq_export->exp_obd; + struct gks_obd *gks = &obd->u.gks; + struct scatterlist sl = { + .page = virt_to_page(data), + .offset = (unsigned long)(data) % PAGE_SIZE, + .length = len + }; + struct crypto_tfm *tfm = gks->gks_key_tfm; + __u8 local_iv[16] = {0}; + + ENTRY; + LASSERT(tfm); + + if (mode == ENCRYPT_DATA) + crypto_cipher_encrypt_iv(tfm, &sl, &sl, (unsigned int)len, + local_iv); + else + crypto_cipher_decrypt_iv(tfm, &sl, &sl, (unsigned int)len, + local_iv); + + RETURN(0); +} + +static int gks_create_key(struct ptlrpc_request *req, int offset) +{ + struct key_context *kctxt; + struct crypto_key *ckey; + + kctxt = lustre_swab_reqbuf(req, offset, sizeof (*kctxt), + lustre_swab_key_context); + + ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, + sizeof (*ckey)); + + crypto_get_gks_mac(req, &kctxt->kc_perm, ckey->ck_mac); + + CDEBUG(D_INFO, "compute mac mac %s by uid %d gid %d mode %d \n", + ckey->ck_mac, kctxt->kc_perm.kp_uid, kctxt->kc_perm.kp_gid, + kctxt->kc_perm.kp_mode); + + get_random_bytes(ckey->ck_key, KEY_SIZE); + + ckey->ck_type = GKS_TYPE; + + CDEBUG(D_INFO, "get key %s\n", ckey->ck_key); + + crypto_encrypt_gks_key(req, ckey->ck_key, KEY_SIZE); + + CDEBUG(D_INFO, "encrypt key %s\n", ckey->ck_key); + + RETURN(0); +} + +static int gks_mac_verification(struct ptlrpc_request *req, + struct crypto_key *key, + struct key_perm *kperm) +{ + __u8 *tmp_mac; + ENTRY; + + OBD_ALLOC(tmp_mac, MAC_SIZE); + + crypto_get_gks_mac(req, kperm, tmp_mac); + + if (!memcmp(tmp_mac, key->ck_mac, MAC_SIZE)) { + OBD_FREE(tmp_mac, MAC_SIZE); + RETURN(0); + } + OBD_FREE(tmp_mac, MAC_SIZE); + RETURN(-EPERM); +} + +static int gks_permission_check(struct key_context *kctxt, + struct key_perm *kperm) +{ + RETURN(0); +} + +static int gks_decrypt_key(struct ptlrpc_request *req, int offset) +{ + struct key_context *kctxt; + struct key_perm *kperm; + struct crypto_key *ckey; + int rc = 0; + + kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt), + lustre_swab_key_context); + + /*authiticating the ops of the mac*/ + rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm); + if (rc != 0) { + CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac); + RETURN(rc); + } + + kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm), + lustre_swab_key_perms); + + rc = gks_permission_check(kctxt, kperm); + if (rc != 0) { + CERROR("permssion check failed\n"); + RETURN(rc); + } + ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, + sizeof (*ckey)); + memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey)); + + rc = crypto_decrypt_gks_key(req, ckey->ck_key, KEY_SIZE); + if (rc != 0) { + CERROR("permssion check failed\n"); + RETURN(rc); + } + + RETURN(0); +} + +static int gks_get_mac(struct ptlrpc_request *req, int offset) +{ + struct key_context *kctxt; + struct key_perm *kperm; + struct crypto_key *ckey; + int rc = 0; + + kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt), + lustre_swab_key_context); + + /*authiticating the ops of the mac*/ + rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm); + if (rc != 0) { + CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac); + RETURN(rc); + } + + kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm), + lustre_swab_key_perms); + + rc = gks_permission_check(kctxt, kperm); + if (rc != 0) { + CERROR("permssion check failed\n"); + RETURN(rc); + } + ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, + sizeof (*ckey)); + + memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey)); + + rc = crypto_get_gks_mac(req, kperm, ckey->ck_mac); + if (rc != 0) { + CERROR("get new mac error %d \n", rc); + RETURN(rc); + } + + RETURN(rc); +} + +int gks_handle(struct ptlrpc_request *req) +{ + int fail = OBD_FAIL_MDS_ALL_REPLY_NET; + int rc; + ENTRY; + + rc = gks_msg_check_version(req->rq_reqmsg); + if (rc) { + CERROR("GKS drop mal-formed request\n"); + RETURN(rc); + } + switch (req->rq_reqmsg->opc) { + case GKS_CONNECT: + DEBUG_REQ(D_INODE, req, "connect"); + rc = target_handle_connect(req); + req->rq_status = rc; /* superfluous? */ + break; + case GKS_DISCONNECT: + DEBUG_REQ(D_INODE, req, "disconnect"); + rc = target_handle_disconnect(req); + req->rq_status = rc; /* superfluous? */ + break; + + case GKS_GET_KEY: { + int size[1] = {sizeof(struct crypto_key)}; + int bufcount = 1; + + DEBUG_REQ(D_INODE, req, "get_key"); + lustre_pack_reply(req, bufcount, size, NULL); + rc = gks_create_key(req, MDS_REQ_REC_OFF); + req->rq_status = rc; /* superfluous? */ + break; + } + case GKS_DECRYPT_KEY: { + int size[1] = {sizeof(struct crypto_key)}; + int bufcount = 1; + + DEBUG_REQ(D_INODE, req, "decrypt_key"); + lustre_pack_reply(req, bufcount, size, NULL); + rc = gks_decrypt_key(req, MDS_REQ_REC_OFF); + req->rq_status = rc; /* superfluous? */ + break; + } + case GKS_GET_MAC: { + int size[1] = {sizeof(struct crypto_key)}; + int bufcount = 1; + + DEBUG_REQ(D_INODE, req, "get_mac"); + lustre_pack_reply(req, bufcount, size, NULL); + rc = gks_get_mac(req, MDS_REQ_REC_OFF); + req->rq_status = rc; /* superfluous? */ + break; + } + default: + req->rq_status = -ENOTSUPP; + rc = ptlrpc_error(req); + RETURN(rc); + } + target_send_reply(req, rc, fail); + RETURN(rc); +} + +static int gkt_setup(struct obd_device *obd, obd_count len, void *buf) +{ + struct gks_obd *gks = &obd->u.gks; + int rc = 0; + ENTRY; + + gks->gks_service = + ptlrpc_init_svc(GKS_NBUFS, GKS_BUFSIZE, GKS_MAXREQSIZE, + GKS_REQUEST_PORTAL, GKC_REPLY_PORTAL, + GKS_SERVICE_WATCHDOG_TIMEOUT, + gks_handle, "gks", obd->obd_proc_entry); + if (!gks->gks_service) { + CERROR("failed to start service\n"); + RETURN(-ENOMEM); + } + + rc = ptlrpc_start_n_threads(obd, gks->gks_service, GKT_NUM_THREADS, + "ll_gkt"); + + RETURN(rc); +} + +static int gkt_cleanup(struct obd_device *obd, int flags) +{ + struct gks_obd *gks = &obd->u.gks; + + ptlrpc_stop_all_threads(gks->gks_service); + ptlrpc_unregister_service(gks->gks_service); + RETURN(0); +} + +int gks_attach(struct obd_device *dev, obd_count len, void *data) +{ + struct lprocfs_static_vars lvars; + + lprocfs_init_vars(gks, &lvars); + return lprocfs_obd_attach(dev, lvars.obd_vars); +} + +int gks_detach(struct obd_device *dev) +{ + return lprocfs_obd_detach(dev); +} + +int gkt_attach(struct obd_device *dev, obd_count len, void *data) +{ + struct lprocfs_static_vars lvars; + + lprocfs_init_vars(gkt, &lvars); + return lprocfs_obd_attach(dev, lvars.obd_vars); +} + +int gkt_detach(struct obd_device *dev) +{ + return lprocfs_obd_detach(dev); +} + +static struct obd_ops gks_obd_ops = { + .o_owner = THIS_MODULE, + .o_attach = gks_attach, + .o_detach = gks_detach, + .o_setup = gks_setup, + .o_cleanup = gks_cleanup, + .o_connect = gks_connect, + .o_disconnect = gks_disconnect, +}; + +static struct obd_ops gkt_obd_ops = { + .o_owner = THIS_MODULE, + .o_attach = gkt_attach, + .o_detach = gkt_detach, + .o_setup = gkt_setup, + .o_cleanup = gkt_cleanup, +}; + +static int __init gks_init(void) +{ + struct lprocfs_static_vars lvars; + + lprocfs_init_vars(gks, &lvars); + class_register_type(&gks_obd_ops, NULL, lvars.module_vars, + LUSTRE_GKS_NAME); + + lprocfs_init_vars(gkt, &lvars); + class_register_type(&gkt_obd_ops, NULL, lvars.module_vars, + LUSTRE_GKT_NAME); + RETURN(0); +} + +static void gks_exit(void) +{ + class_unregister_type(LUSTRE_GKS_NAME); + class_unregister_type(LUSTRE_GKT_NAME); +} + +MODULE_AUTHOR("Cluster File Systems, Inc. "); +MODULE_DESCRIPTION("Lustre GS Server (GS)"); +MODULE_LICENSE("GPL"); + +module_init(gks_init); +module_exit(gks_exit); + diff --git a/lustre/sec/gks/lproc_gks.c b/lustre/sec/gks/lproc_gks.c new file mode 100644 index 0000000..4849941c --- /dev/null +++ b/lustre/sec/gks/lproc_gks.c @@ -0,0 +1,38 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (C) 2002 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#define DEBUG_SUBSYSTEM S_CLASS + +#include +#include + +static struct lprocfs_vars lprocfs_gks_module_vars[] = { {0} }; +static struct lprocfs_vars lprocfs_gks_obd_vars[] = { {0} }; + +static struct lprocfs_vars lprocfs_gkt_module_vars[] = { {0} }; +static struct lprocfs_vars lprocfs_gkt_obd_vars[] = { {0} }; + +static struct lprocfs_vars lprocfs_gkc_module_vars[] = { {0} }; +static struct lprocfs_vars lprocfs_gkc_obd_vars[] = { {0} }; + +LPROCFS_INIT_VARS(gks, lprocfs_gks_module_vars, lprocfs_gks_obd_vars) +LPROCFS_INIT_VARS(gkt, lprocfs_gkt_module_vars, lprocfs_gkt_obd_vars) +LPROCFS_INIT_VARS(gkc, lprocfs_gkc_module_vars, lprocfs_gkc_obd_vars) diff --git a/lustre/smfs/fsfilt.c b/lustre/smfs/fsfilt.c index 7dbfd03..977069b 100644 --- a/lustre/smfs/fsfilt.c +++ b/lustre/smfs/fsfilt.c @@ -750,6 +750,7 @@ static int fsfilt_smfs_get_xattr(struct inode *inode, char *name, #define XATTR_LUSTRE_MDS_MEA_EA "mea" #define XATTR_LUSTRE_MDS_MID_EA "mid" #define XATTR_LUSTRE_MDS_SID_EA "sid" +#define XATTR_LUSTRE_MDS_KEY_EA "key" static int fsfilt_smfs_set_md(struct inode *inode, void *handle, void *lmm, int lmm_size, enum ea_type type) @@ -777,6 +778,11 @@ static int fsfilt_smfs_set_md(struct inode *inode, void *handle, XATTR_LUSTRE_MDS_MID_EA, lmm, lmm_size); break; + case EA_KEY: + rc = fsfilt_smfs_set_xattr(inode, handle, + XATTR_LUSTRE_MDS_KEY_EA, + lmm, lmm_size); + break; default: rc = -EINVAL; } diff --git a/lustre/smfs/mds_kml.c b/lustre/smfs/mds_kml.c index ff88cba..196a392 100644 --- a/lustre/smfs/mds_kml.c +++ b/lustre/smfs/mds_kml.c @@ -107,7 +107,7 @@ static int mds_rec_setxattr_pack(char *buffer, struct dentry *dentry, LASSERT(kbuf && name); tmp = mdc_setattr_pack(msg, 0, op_data, NULL, name, strlen(name), - kbuf->buf, kbuf->buf_size); + kbuf->buf, kbuf->buf_size, NULL, 0); OBD_FREE(op_data, sizeof(*op_data)); rec = (struct mds_rec_setattr *)lustre_msg_buf(msg, 0, 0); @@ -152,7 +152,8 @@ static int mds_rec_setattr_pack(char *buffer, struct dentry *dentry, msg = (struct lustre_msg *)(buffer + sizeof(*mkpi)); lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL); - tmp = mdc_setattr_pack(msg, 0, op_data, iattr, ea, ealen, NULL, 0); + tmp = mdc_setattr_pack(msg, 0, op_data, iattr, ea, ealen, + NULL, 0, NULL, 0); OBD_FREE(op_data, sizeof(*op_data)); /* FIXME-WANGDI: there are maybe some better ways to set the time diff --git a/lustre/tests/cfg/lmv.sh b/lustre/tests/cfg/lmv.sh index 99cbfdd..d1cd232 100644 --- a/lustre/tests/cfg/lmv.sh +++ b/lustre/tests/cfg/lmv.sh @@ -9,6 +9,8 @@ mds3_HOST=$mds1_HOST ost_HOST=${ost_HOST:-$OSTNODE} ost2_HOST=${ost2_HOST:-$ost_HOST} client_HOST=${client_HOST:-$CLIENT} +gsk_HOST=${gsk_HOST:-$MDSNODE} + NETTYPE=${NETTYPE:-tcp} MOUNT=${MOUNT:-"/mnt/lustre"} diff --git a/lustre/tests/lgs.sh b/lustre/tests/lgs.sh new file mode 100755 index 0000000..f0f893b --- /dev/null +++ b/lustre/tests/lgs.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -e + +export PATH=`dirname $0`/../utils:$PATH + +config=${1:-lgs.xml} + +LMC=${LMC:-lmc} +TMP=${TMP:-/tmp} + +MDSSIZE=${MDSSIZE:-100000} +MDSCOUNT=${MDSCOUNT:-3} +OSTDEV=${OSTDEV:-$TMP/ost1-`hostname`} +OSTSIZE=${OSTSIZE:-200000} +OSTCOUNT=${OSTCOUNT:-1} + +DEF_FSTYPE=`test "x$(uname -r | grep -o '2.6')" = "x2.6" && echo "ldiskfs" || echo "ext3"` +FSTYPE=${FSTYPE:-$DEF_FSTYPE} +#used only if FSTYPE == smfs, otherwise ignored by lconf +MDS_BACKFSTYPE=${MDS_BACKFSTYPE:-$DEF_FSTYPE} +OST_BACKFSTYPE=${OST_BACKFSTYPE:-$DEF_FSTYPE} + +# 1 to config an echo client instead of llite +ECHO_CLIENT=${ECHO_CLIENT:-} + +STRIPE_BYTES=65536 +STRIPES_PER_OBJ=0 + +MOUNT=${MOUNT:-/mnt/lustre} + +# specific journal size for the ost, in MB +JSIZE=${JSIZE:-0} +JARG="" +[ "$JSIZE" -gt 0 ] && JARG="--journal_size $JSIZE" + +rm -f $config + +# create nodes +${LMC} -m $config --add node --node localhost || exit 10 +${LMC} -m $config --add net --node localhost --nid `hostname` --nettype tcp || exit 11 + +# configure mds server +${LMC} -m $config --add lmv --lmv lmv1 || exit 12 + +for num in `seq $MDSCOUNT`; do + MDSDEV=$TMP/mds${num}-`hostname` + ${LMC} -m $config --format --add mds --node localhost --mds mds${num} \ + --lmv lmv1 --fstype $FSTYPE --backfstype $MDS_BACKFSTYPE --dev $MDSDEV \ + --size $MDSSIZE || exit 13 +done + +${LMC} -m $config --add lov --lov lov1 --lmv lmv1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20 + +# configure ost +for num in `seq $OSTCOUNT`; do + OST=ost$num + DEVPTR=OSTDEV$num + eval $DEVPTR=${!DEVPTR:=$TMP/$OST-`hostname`} + ${LMC} -m $config --add ost --node localhost --lov lov1 --ost $OST --fstype $FSTYPE --backfstype $OST_BACKFSTYPE --dev ${!DEVPTR} --size $OSTSIZE $JARG || exit 30 +done + +${LMC} -m $config --add gks --gks gks1 --node localhost || exit 13 + +${LMC} -m $config --add mtpt --node localhost --path $MOUNT --lmv lmv1 --lov lov1 --gks gks1 || exit 40 diff --git a/lustre/tests/sanity-crypto.sh b/lustre/tests/sanity-crypto.sh new file mode 100755 index 0000000..1aaba39 --- /dev/null +++ b/lustre/tests/sanity-crypto.sh @@ -0,0 +1,112 @@ +#!/bin/sh + +set -e + +# +# This test needs to be run on the client +# + +LUSTRE=${LUSTRE:-`dirname $0`/..} +. $LUSTRE/tests/test-framework.sh + +init_test_env $@ + +. ${CONFIG:=$LUSTRE/tests/cfg/lmv.sh} + +build_test_filter + +assert_env MDSCOUNT + +if [ `using_krb5_sec $SECURITY` == 'n' ] ; then + ALWAYS_EXCEPT="0c $ALWAYS_EXCEPT" +fi + + +gen_config() { + rm -f $XMLCONFIG + + if [ "$MDSCOUNT" -gt 1 ]; then + add_lmv lmv1_svc + for mds in `mds_list`; do + MDSDEV=$TMP/${mds}-`hostname` + add_mds $mds --dev $MDSDEV --size $MDSSIZE --lmv lmv1_svc + done + add_lov_to_lmv lov1 lmv1_svc --stripe_sz $STRIPE_BYTES \ + --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 + MDS=lmv1 + else + add_mds $SINGLEMDS --dev $MDSDEV --size $MDSSIZE + if [ ! -z "$$SINGLEMDSfailover_HOST" ]; then + add_mdsfailover $SINGLEMDS --dev $MDSDEV --size $MDSSIZE + fi + add_lov lov1 $SINGLEMDS --stripe_sz $STRIPE_BYTES \ + --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 + MDS=$SINGLEMDS_svc + fi + add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE + add_ost ost2 --lov lov1 --dev ${OSTDEV}-2 --size $OSTSIZE + add_gsk gsk + add_client client $MDS --lov lov1 --gss gsk_svc --path $MOUNT +} + +build_test_filter + +cleanup() { + # make sure we are using the primary MDS, so the config log will + # be able to clean up properly. + activemds=`facet_active $SINGLEMDS` + if [ $activemds != "$SINGLEMDS" ]; then + fail $SINGLEMDS + fi + + umount $MOUNT2 || true + umount $MOUNT || true + rmmod llite + + stop_gsk gsk + for mds in `mds_list`; do + stop $mds ${FORCE} $MDSLCONFARGS + done + stop ost2 ${FORCE} --dump cleanup.log + stop ost ${FORCE} --dump cleanup.log + stop_lgssd + stop_lsvcgssd +} + +if [ "$ONLY" == "cleanup" ]; then + sysctl -w portals.debug=0 || true + cleanup + exit +fi + +SETUP=${SETUP:-"setup"} +CLEANUP=${CLEANUP:-"cleanup"} + +setup() { + gen_config + + start_krb5_kdc || exit 1 + start_lsvcgssd || exit 2 + start_lgssd || exit 3 + start ost --reformat $OSTLCONFARGS + start ost2 --reformat $OSTLCONFARGS + [ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE + for mds in `mds_list`; do + start $mds --reformat $MDSLCONFARGS + done + set -vx + start_gsk gsk || exit 4 + set -e + grep " $MOUNT " /proc/mounts || zconf_mount `hostname` $MOUNT + grep " $MOUNT2 " /proc/mounts || zconf_mount `hostname` $MOUNT2 +} + +$SETUP + +if [ "$ONLY" == "setup" ]; then + exit 0 +fi + +mkdir -p $DIR +$CLEANUP + diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index c560100..a720fa3 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -76,7 +76,7 @@ start() { facet=$1 shift active=`facet_active $facet` - do_facet $facet $LCONF --select ${facet}_svc=${active}_facet \ + do_facet $facet $LCONF --select ${facet}_svc=${active}_facet -v \ --node ${active}_facet --ptldebug $PTLDEBUG --subsystem $SUBSYSTEM \ --mds_sec $SECURITY $@ $XMLCONFIG } @@ -377,6 +377,26 @@ del_ost() { shift do_lmc --delete ost --node ${facet}_facet --ost ${facet}_svc $* } +start_gsk() { + facet=$1 + shift + rm -f ${facet}active + add_facet $facet + do_facet $facet $LCONF --node ${facet}_facet --ptldebug $PTLDEBUG $* $XMLCONFIG +} +stop_gsk() { + facet=$1 + shift + do_facet $facet $LCONF --node ${facet}_facet --cleanup $* $XMLCONFIG +} + +add_gsk() { + facet=$1 + shift + rm -f ${facet}active + add_facet $facet + do_lmc --add gss --gss ${facet}_svc --node ${facet}_facet $* +} add_cmobd() { facet=$1 cache_facet=$2 diff --git a/lustre/utils/lconf b/lustre/utils/lconf index bd47b63..f6f36f3 100755 --- a/lustre/utils/lconf +++ b/lustre/utils/lconf @@ -714,10 +714,10 @@ class LCTLInterface: return out # dump mount options - def mount_option(self, profile, osc, mdc): + def mount_option(self, profile, osc, mdc, gkc): cmds = """ - mount_option %s %s %s - quit""" % (profile, osc, mdc) + mount_option %s %s %s %s + quit""" % (profile, osc, mdc, gkc) self.run(cmds) # delete mount options @@ -1726,6 +1726,66 @@ class LMV(Module): def correct_level(self, level, op=None): return level +class GKD(Module): + def __init__(self,db): + Module.__init__(self, 'GKD', db) + target_uuid = self.db.get_first_ref('target') + self.target = self.db.lookup(target_uuid) + self.name = self.target.getName() + + active_uuid = get_active_target(self.target) + if not active_uuid: + panic("No target device found:", target_uuid) + if active_uuid == self.uuid: + self.active = 1 + else: + self.active = 0 + + self.uuid = target_uuid + def prepare(self): + if is_prepared(self.name): + return + if not self.active: + debug(self.uuid, "not active") + return + run_acceptors() + + lctl.newdev("gks", self.name, self.uuid, setup ="") + if not is_prepared('GKT'): + lctl.newdev("gkt", 'GKT', 'GKT_UUID', setup ="") + + def cleanup(self): + if not self.active: + debug(self.uuid, "not active") + return + self.info() + if is_prepared(self.name): + try: + lctl.cleanup(self.name, self.uuid, config.force, + config.failover) + except CommandError, e: + log(self.module_name, "cleanup failed: ", self.name) + e.dump() + cleanup_error(e.rc) + Module.cleanup(self) + if is_prepared('GKT'): + try: + lctl.cleanup("GKT", "GKT_UUID", config.force, + config.failover) + except CommandError, e: + print "cleanup failed: ", self.name + e.dump() + cleanup_error(e.rc) + + def add_module(self, manager): + if self.active: + manager.add_lustre_module('sec/gks', 'gks') + manager.add_lustre_module('sec/gks', 'gkc') + + def correct_level(self, level, op=None): + return level + + class CONFDEV(Module): def __init__(self, db, name, target_uuid, uuid): Module.__init__(self, 'CONFDEV', db) @@ -1960,7 +2020,7 @@ class CONFDEV(Module): lctl.clear_log(self.name, self.target.getName()) lctl.record(self.name, self.target.getName()) client.prepare() - lctl.mount_option(self.target.getName(), client.get_name(), "") + lctl.mount_option(self.target.getName(), client.get_name(), "", "") lctl.end_record() config.cleanup = 1 @@ -2522,6 +2582,13 @@ class Client(Module): e.dump() cleanup_error(e.rc) +class GKC(Client): + def __init__(self, db, uuid, fs_name): + Client.__init__(self, db, uuid, 'gkc', fs_name) + + def permits_inactive(self): + return 0 + class MDC(Client): def __init__(self, db, uuid, fs_name): Client.__init__(self, db, uuid, 'mdc', fs_name) @@ -2808,7 +2875,15 @@ class Mountpoint(Module): if not self.mds_uuid: self.mds_uuid = fs.get_first_ref('mds') self.obd_uuid = fs.get_first_ref('obd') - client_uuid = generate_client_uuid(self.name) + self.gks_uuid =fs.get_first_ref('gks') + client_uuid = generate_client_uuid(self.name) + + self.oss_sec = self.db.get_val('oss_sec','null') + self.mds_sec = self.db.get_val('mds_sec','null') + if config.mds_sec: + self.mds_sec = config.mds_sec + if config.oss_sec: + self.oss_sec = config.oss_sec self.oss_sec = self.db.get_val('oss_sec','null') self.mds_sec = self.db.get_val('mds_sec','null') @@ -2827,7 +2902,9 @@ class Mountpoint(Module): self.vosc = VOSC(ost, client_uuid, self.name, self.name) self.vmdc = VMDC(mds, client_uuid, self.name, self.name) - + + if self.gks_uuid: + self.gkc = get_gkc(db, client_uuid, self.name, self.gks_uuid) def prepare(self): if not config.record and fs_is_mounted(self.path): log(self.path, "already mounted.") @@ -2836,12 +2913,18 @@ class Mountpoint(Module): self.vosc.prepare() self.vmdc.prepare() + if self.gks_uuid: + self.gkc.prepare() self.info(self.path, self.mds_uuid, self.obd_uuid) if config.record or config.lctl_dump: - lctl.mount_option(local_node_name, self.vosc.get_name(), - self.vmdc.get_name()) - return + if self.gks_uuid: + lctl.mount_option(local_node_name, self.vosc.get_name(), + self.vmdc.get_name(), self.gkc.get_name()) + else: + lctl.mount_option(local_node_name, self.vosc.get_name(), + self.vmdc.get_name(), "") + return if config.clientoptions: if self.clientoptions: @@ -2854,8 +2937,12 @@ class Mountpoint(Module): # so replace it with Lustre async self.clientoptions = string.replace(self.clientoptions, "async", "lasync") - cmd = "mount -t lustre_lite -o osc=%s,mdc=%s,mds_sec=%s,oss_sec=%s%s %s %s" % \ - (self.vosc.get_name(), self.vmdc.get_name(), self.mds_sec, + if self.gks_uuid: + gkc_name = self.gkc.get_name(); + else: + gkc_name = "null" + cmd = "mount -t lustre_lite -o osc=%s,mdc=%s,gkc=%s,mds_sec=%s,oss_sec=%s%s %s %s" % \ + (self.vosc.get_name(), self.vmdc.get_name(), gkc_name, self.mds_sec, self.oss_sec, self.clientoptions, config.config, self.path) run("mkdir", self.path) ret, val = run(cmd) @@ -2883,12 +2970,15 @@ class Mountpoint(Module): self.vmdc.cleanup() self.vosc.cleanup() + if self.gks_uuid: + self.gkc.cleanup() def add_module(self, manager): self.vosc.add_module(manager) self.vmdc.add_module(manager) manager.add_lustre_module('llite', 'llite') - + if self.gks_uuid: + manager.add_lustre_module('sec/gks', 'gkc') def correct_level(self, level, op=None): return level @@ -2924,8 +3014,10 @@ def getServiceLevel(self): ret = 30 elif type in ('mdsdev',): ret = 40 - elif type in ('lmv',): + elif type in ('lmv', 'cobd',): ret = 45 + elif type in ('gkd'): + ret = 50 elif type in ('cmobd', 'cobd',): ret = 60 elif type in ('mountpoint', 'echoclient'): @@ -2972,6 +3064,13 @@ def get_mdc(db, fs_name, mds_uuid): mdc = MDC(mds_db, mds_uuid, fs_name) return mdc +def get_gkc(db, uuid, fs_name, gks_uuid): + gks_db = db.lookup(gks_uuid); + if not gks_db: + error("no gks:", gks_uuid) + gkc = GKC(gks_db, uuid, fs_name) + return gkc + ############################################################ # routing ("rooting") @@ -3110,6 +3209,8 @@ def newService(db): n = ECHO_CLIENT(db) elif type == 'lmv': n = LMV(db) + elif type == 'gkd': + n = GKD(db) else: panic ("unknown service type:", type) return n diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 8ff3dcc..807a01b 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -315,7 +315,7 @@ command_t cmdlist[] = { "setup mds/ost from the llog file\n" "usage: start "}, {"mount_option", jt_lcfg_mount_option, 0, - "usage: mount_option profile osc_name [mdc_name] \n"}, + "usage: mount_option profile osc_name [mdc_name] [gsc_name] \n"}, {"del_mount_option", jt_lcfg_del_mount_option, 0, "usage: del_mount_option profile\n"}, {"set_timeout", jt_lcfg_set_timeout, 0, @@ -365,12 +365,15 @@ command_t cmdlist[] = { {"llog_remove", jt_llog_remove, 0, "remove one log from catalog, erase it from disk.\n" "usage: llog_remove "}, - + /* Misc commands */ {"flush_cred", jt_flush_cred, 0, "flush the client side credential.\n" "usage: flush_cred [mountpoint]..."}, - + {"set_crypt", jt_set_lkey_type, 0, + "set lustre key management type, only support gsk and mdk\n" + "usage: set_crypt [dir] [gsk|mdk]...."}, + /* Debug commands */ {"======== debug =========", jt_noop, 0, "debug"}, {"debug_daemon", jt_dbg_debug_daemon, 0, diff --git a/lustre/utils/lmc b/lustre/utils/lmc index 620936a..b50b376 100755 --- a/lustre/utils/lmc +++ b/lustre/utils/lmc @@ -178,6 +178,9 @@ Object creation command summary: --master_obd obd_name --cache_obd obd_name +--add gks + --gks gks_name + --commit - Close a configuration version, and start a new one """ @@ -283,6 +286,10 @@ lmc_options = [ # lmv ('lmv', "Specify LMV name.", PARAM,""), + + #gks name + ('gks', "Specify gks name.", PARAM,""), + ] def error(*args): @@ -536,6 +543,17 @@ class GenConfig: lmv = self.newService("lmv", name, uuid) return lmv + def gks(self, name, uuid, gkd_uuid): + gks = self.newService("gks", name, uuid) + gks.appendChild(self.ref("active", gkd_uuid)) + return gks + + def gkd(self, name, uuid, node_uuid, gks_uuid): + gkd = self.newService("gkd", name, uuid) + gkd.appendChild(self.ref("node", node_uuid)) + gkd.appendChild(self.ref("target", gks_uuid)) + return gkd + def mds(self, name, uuid, mdd_uuid, group="", lmv=""): mds = self.newService("mds", name, uuid) mds.appendChild(self.ref("active", mdd_uuid)) @@ -611,10 +629,11 @@ class GenConfig: self.addElement(mtpt, "oss_sec", oss_sec) return mtpt - def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid): + def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid): fs = self.newService("filesystem", name, uuid) fs.appendChild(self.ref("mds", mds_uuid)) fs.appendChild(self.ref("obd", obd_uuid)) + fs.appendChild(self.ref("gks", gks_uuid)) if mgmt_uuid: fs.appendChild(self.ref("mgmt", mgmt_uuid)) return fs @@ -978,6 +997,37 @@ def add_route(gen, lustre, options): node_add_profile(gen, node, "routetbl", rtbl_uuid) rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id, lo, hi)) + +def add_gks(gen, lustre, options): + """ create a gks """ + node_name = get_option(options, 'node') + gks_name = get_option(options, 'gks') + if not gks_name: + gks_name = new_name('GKS_'+ node_name) + + gkd_name = new_name("GKD_" + gks_name + "_" + node_name) + gkd_uuid = new_uuid(gkd_name) + + gks_uuid = name2uuid(lustre, gks_name, 'gks', fatal=0) + + if not gks_uuid: + gks_uuid = new_uuid(gks_name) + gks = gen.gks(gks_name, gks_uuid, gkd_uuid) + lustre.appendChild(gks) + else: + gks = lookup(lustre, gks_uuid) + + # add gkd profile + node_uuid = name2uuid(lustre, node_name, 'node') + node = findByName(lustre, node_name, "node") + node_add_profile(gen, node, "gkd", gkd_uuid) + net_uuid = get_net_uuid(lustre, node_name) + if not net_uuid: + error("NODE: ", node_name, "not found") + + gkd = gen.gkd(gkd_name, gkd_uuid, node_uuid, gks_uuid) + lustre.appendChild(gkd) + def add_mds(gen, lustre, options): node_name = get_option(options, 'node') @@ -1450,7 +1500,7 @@ def add_lmv(gen, lustre, options): lmv = gen.lmv(name, uuid) lustre.appendChild(lmv) - + def find_client(lustre, mds_uuid, client_uuid): mds = lookup(lustre, mds_uuid) clients = mds.getElementsByTagName('client_ref') @@ -1461,7 +1511,7 @@ def find_client(lustre, mds_uuid, client_uuid): return 1 return 0 -def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid): +def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid): fs_name = new_name("FS_fsname") fs_uuid = new_uuid(fs_name) @@ -1472,12 +1522,12 @@ def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid): mds.appendChild(gen.ref("client", obd_uuid)) fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, - obd_uuid, mgmt_uuid) + obd_uuid, mgmt_uuid, gks_uuid) lustre.appendChild(fs) return fs_uuid -def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name): +def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name, gks_name): mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0) if not mds_uuid: mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0) @@ -1499,10 +1549,14 @@ def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name): else: mgmt_uuid = '' + if gks_name: + gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1) + else: + gks_uuid = '' fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid) if not fs_uuid: fs_uuid = new_filesystem(gen, lustre, mds_uuid, - obd_uuid, mgmt_uuid) + obd_uuid, mgmt_uuid, gks_uuid) return fs_uuid def add_mtpt(gen, lustre, options): @@ -1518,6 +1572,7 @@ def add_mtpt(gen, lustre, options): lov_name = get_option(options, 'lov') ost_name = get_option(options, 'ost') mds_name = get_option(options, 'mds') + gks_name = get_option(options, 'gks') if mds_name == '': mds_name = get_option(options, 'lmv') if mds_name == '': @@ -1537,7 +1592,7 @@ def add_mtpt(gen, lustre, options): if fs_name == '': mgmt_name = get_option(options, 'mgmt') - fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name) + fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name, gks_name) else: fs_uuid = name2uuid(lustre, fs_name, tag='filesystem') @@ -1698,6 +1753,8 @@ def add(devtype, gen, lustre, options): add_mgmt(gen, lustre, options) elif devtype == 'lmv': add_lmv(gen, lustre, options) + elif devtype == 'gks': + add_gks(gen, lustre, options) else: error("unknown device type:", devtype) diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index acb3bee..e446d55 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -550,7 +550,7 @@ int jt_lcfg_mount_option(int argc, char **argv) struct lustre_cfg *lcfg; int i; - if (argc < 3 || argc > 4) + if (argc < 3 || argc > 5) return CMD_HELP; lustre_cfg_bufs_reset(&bufs, lcfg_devname); diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index ebed1b3..80b7130 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -1981,6 +1981,104 @@ int jt_obd_recover(int argc, char **argv) return rc; } +int jt_set_lkey_type(int argc, char **argv) +{ + struct obd_ioctl_data data; + char *dir, *type; + int rc, fd; + + if (argc < 3 || argc > 4) + return CMD_HELP; + + dir = argv[1]; + type = argv[2]; + + IOC_INIT(data); + + data.ioc_inllen1 = strlen(type) + 1; + data.ioc_inlbuf1 = type; + + IOC_PACK(argv[0], data); + + fd = open(dir, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "open \"%s\" failed: %s\n", dir, + strerror(errno)); + return -1; + } + + rc = ioctl(fd, LL_IOC_KEY_TYPE, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: ioctl error: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + } + close(fd); + return rc; +} + +int jt_disable_crypto(int argc, char **argv) +{ + struct obd_ioctl_data data; + char *file; + int rc, fd; + + if (argc < 2 || argc > 3) + return CMD_HELP; + + file = argv[1]; + + IOC_INIT(data); + + IOC_PACK(argv[0], data); + + fd = open(file, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "open \"%s\" failed: %s\n", file, + strerror(errno)); + return -1; + } + + rc = ioctl(fd, LL_IOC_DISABLE_CRYPTO, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: ioctl error: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + } + close(fd); + + return rc; +} + +int jt_enable_crypto(int argc, char **argv) +{ + struct obd_ioctl_data data; + char *file; + int rc, fd; + + if (argc < 3 || argc > 4) + return CMD_HELP; + + file = argv[1]; + + IOC_INIT(data); + + IOC_PACK(argv[0], data); + + fd = open(file, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "open \"%s\" failed: %s\n", file, + strerror(errno)); + return -1; + } + + rc = ioctl(fd, LL_IOC_ENABLE_CRYPTO, buf); + if (rc < 0) { + fprintf(stderr, "error: %s: ioctl error: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + } + close(fd); + return rc; +} + int jt_obd_mdc_lookup(int argc, char **argv) { diff --git a/lustre/utils/obdctl.h b/lustre/utils/obdctl.h index 02fbe8a..e507a7e 100644 --- a/lustre/utils/obdctl.h +++ b/lustre/utils/obdctl.h @@ -95,7 +95,9 @@ int jt_obd_reint_sync(int argc, char **argv); int jt_obd_cache_on(int argc, char **argv); int jt_obd_cache_off(int argc, char **argv); int jt_obd_snap_add(int argc, char **argv); - +int jt_set_lkey_type(int argc, char **argv); +int jt_disable_crypto(int argc, char **argv); +int jt_enable_crypto(int argc, char **argv); int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg); int parse_devname(char *func, char *name); char *jt_cmdname(char *func); -- 1.8.3.1