Am Freitag, den 11.11.2011, 14:33 +0100 schrieb Kay Sievers: > On Tue, Sep 20, 2011 at 14:26, Kay Sievers <kay.siev...@vrfy.org> wrote: > > On Tue, Sep 20, 2011 at 12:58, Lennart Poettering > > <lenn...@poettering.net> wrote: > >> On Tue, 20.09.11 11:36, Ian Kent (ra...@themaw.net) wrote: > >> > >>> > This is a bug in the kernel, and it should be fixed in the kernel (which > >>> > would mean the kernel folks have to define a new version of this > >>> > struct/ioctl which fixes this). If that's defined we can then add > >>> > support for this into systemd. Could you file a bug about this please on > >>> > the kernel bugzilla? (please cc me, or post the url here!) > >>> > >>> Yes, it is a mistake that I made but it is a bad idea to change > >>> something that will cause widespread failure of existing binaries and > >>> that's why the discrepancy persists and will continue to do so. > >> > >> I am not expecting this to be changed in the kernel. Instead I expect > >> that the kernel API is extended with a correct version of the same data > >> structure. If the kernel broke it the kernel should fix it. > >> > >>> I chose to compensate for it in user space and to advise anyone that > >>> encountered the problem on how to handle it and I have had no reports of > >>> problems in autofs since I added the size calculation (which was a long > >>> time ago now). > >> > >> Well, it's a workaround in userspace. Fix the kernel. Add a second union > >> or something which can be used by newer clients. > >> > >>> > I am sorry but I am pretty sure I want to keep the compat kludges for > >>> > broken things in systemd at a minimum, adding such a work around looks > >>> > like the wrong way to me. We generally try to fix problems where they > >>> > are these days, not where we notice them. > >>> > >>> Sure, it is unfortunate but, as far as the autofs kernel module is > >>> concerned the decision about this was made a long time ago and, yes it > >>> isn't what we want but the breakage it would have caused then and the > >>> breakage it would cause now is too great. > >> > >> Adding a corrected version will not break anything. This is not about > >> replacing the current borked interface, but simply by adding a fixed > >> version that we can use from userspace without ugly compat glue. > >> > >> Fix the problems where they are, don't work around them where they aren't. > > > > I can only second that. > > > > Please add a new definition, leave the old around, and do not require > > userspace to do wild things, like compare static lists of > > architectures to work around things that can be expected to just work. > > Ian, is this fixed in the meantime? If not, mind fixing the kernel bug > and introduce an non-broken version of the kernel interface. > > We like to have this fixed in systemd, but are still reluctant to > compile lists of static 32 vs. 64 architecture bit matches in init.
Hi, just did this quick hack. It compiles, but I didn't test it: >From 3e71ead349d179302452798fd3bc9305a5477d22 Mon Sep 17 00:00:00 2001 From: Thomas Meyer <tho...@m3y3r.de> Date: Sun, 13 Nov 2011 13:13:57 +0100 Subject: [PATCH] Add autofs_v6_packet with same packet size on x86 and x86_64. autofs_v5_packet is 300 bytes on x86 and 304 bytes on x86_64. This leads to an error in at least systemd when running a x86_64 kernel on an x86 userspace. Fix this by adding a new protocol version 6 packet that has the same size on x86 and x86_64. Signed-off-by: Thomas Meyer <tho...@m3y3r.de> --- fs/autofs4/inode.c | 30 ++++++++++++++++++++++------ fs/autofs4/waitq.c | 47 +++++++++++++++++++++++++++++++-------------- include/linux/auto_fs4.h | 19 ++++++++++++++++- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 8179f1a..10a57fc 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c @@ -197,6 +197,28 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, return (*pipefd < 0); } +static bool check_protocol_version(int minproto, int maxproto) +{ + bool rc = true; + + if (minproto > maxproto || maxproto < minproto) { + printk("autofs: protocol min(%d)/max(%d) version error!", + minproto, maxproto); + rc = false; + } + + if (maxproto < AUTOFS_MIN_PROTO_VERSION || + minproto > AUTOFS_MAX_PROTO_VERSION) { + printk("autofs: kernel does not match daemon version " + "daemon (%d, %d) kernel (%d, %d)\n", + minproto, maxproto, + AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION); + rc = false; + } + + return rc; +} + int autofs4_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; @@ -269,14 +291,8 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) root_inode->i_op = &autofs4_dir_inode_operations; /* Couldn't this be tested earlier? */ - if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION || - sbi->min_proto > AUTOFS_MAX_PROTO_VERSION) { - printk("autofs: kernel does not match daemon version " - "daemon (%d, %d) kernel (%d, %d)\n", - sbi->min_proto, sbi->max_proto, - AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION); + if(check_protocol_version(sbi->min_proto, sbi->max_proto) == false) goto fail_dput; - } /* Establish highest kernel protocol version */ if (sbi->max_proto > AUTOFS_MAX_PROTO_VERSION) diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index e1fbdee..2e455be 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -99,6 +99,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, struct autofs_packet_hdr hdr; union autofs_packet_union v4_pkt; union autofs_v5_packet_union v5_pkt; + struct autofs_v6_packet v6_pkt; } pkt; struct file *pipe = NULL; size_t pktsz; @@ -137,7 +138,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, break; } /* - * Kernel protocol v5 packet for handling indirect and direct + * Kernel protocol v5/v6 packet for handling indirect and direct * mount missing and expire requests */ case autofs_ptype_missing_indirect: @@ -145,20 +146,36 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, case autofs_ptype_missing_direct: case autofs_ptype_expire_direct: { - struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; - - pktsz = sizeof(*packet); - - packet->wait_queue_token = wq->wait_queue_token; - packet->len = wq->name.len; - memcpy(packet->name, wq->name.name, wq->name.len); - packet->name[wq->name.len] = '\0'; - packet->dev = wq->dev; - packet->ino = wq->ino; - packet->uid = wq->uid; - packet->gid = wq->gid; - packet->pid = wq->pid; - packet->tgid = wq->tgid; + if(sbi->version == 5) { + struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; + + packet->wait_queue_token = wq->wait_queue_token; + packet->len = wq->name.len; + memcpy(packet->name, wq->name.name, wq->name.len); + packet->name[wq->name.len] = '\0'; + packet->dev = wq->dev; + packet->ino = wq->ino; + packet->uid = wq->uid; + packet->gid = wq->gid; + packet->pid = wq->pid; + packet->tgid = wq->tgid; + pktsz = sizeof(packet); + } + if(sbi->version == 6) { + struct autofs_v6_packet *packet = &pkt.v6_pkt; + + packet->wait_queue_token = wq->wait_queue_token; + packet->len = wq->name.len; + memcpy(packet->name, wq->name.name, wq->name.len); + packet->name[wq->name.len] = '\0'; + packet->dev = wq->dev; + packet->ino = wq->ino; + packet->uid = wq->uid; + packet->gid = wq->gid; + packet->pid = wq->pid; + packet->tgid = wq->tgid; + pktsz = sizeof(packet); + } break; } default: diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index e02982f..e16b105 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h @@ -20,9 +20,9 @@ #undef AUTOFS_MIN_PROTO_VERSION #undef AUTOFS_MAX_PROTO_VERSION -#define AUTOFS_PROTO_VERSION 5 +#define AUTOFS_PROTO_VERSION 6 #define AUTOFS_MIN_PROTO_VERSION 3 -#define AUTOFS_MAX_PROTO_VERSION 5 +#define AUTOFS_MAX_PROTO_VERSION 6 #define AUTOFS_PROTO_SUBVERSION 2 @@ -154,6 +154,21 @@ union autofs_v5_packet_union { autofs_packet_expire_direct_t expire_direct; }; +/* autofs v6 common packet struct */ +/* packed structure for same packet size on x86 and x86_64 */ +struct autofs_v6_packet { + struct autofs_packet_hdr hdr; + autofs_wqt_t wait_queue_token; + __u32 dev; + __u64 ino; + __u32 uid; + __u32 gid; + __u32 pid; + __u32 tgid; + __u32 len; + char name[NAME_MAX+1]; +} __attribute__ ((packed)); + #define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int) #define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI #define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI -- 1.7.7.1 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel