|
From: Mike S. <ma...@gm...> - 2012-01-20 18:36:54
|
On Fri, Jan 20, 2012 at 10:47 AM, Miklos Szeredi <mi...@sz...> wrote:
> Here's an untested patch to introduce fuse_terminate(). This should do
> what you need.
>
> Can you please test?
>
> Thanks,
> Miklos
>
>
> diff --git a/include/fuse.h b/include/fuse.h
> index b05152d..2f9fbe6 100644
> --- a/include/fuse.h
> +++ b/include/fuse.h
> @@ -670,10 +670,27 @@ int fuse_loop(struct fuse *f);
> /**
> * Exit from event loop
> *
> + * This sets the exit flag on the event loop. Note: this will only
> + * cause immediate exit if called from a signal handler or from a
> + * filesystem operation. Otherwise the loop will exit on the next
> + * event (filesystem operation or signal).
> + *
> * @param f the FUSE handle
> */
> void fuse_exit(struct fuse *f);
>
> +
> +/**
> + * Terminate the event loop
> + *
> + * Similar to fuse_exit() but also sends SIGTERM to the loop, causing
> + * immediate exit even if not called from a filesystem operation or
> + * signal handler.
> + *
> + * @param f the FUSE handle
> + */
> +void fuse_terminate(struct fuse *f);
> +
> /**
> * FUSE event loop with multiple threads
> *
> diff --git a/lib/fuse.c b/lib/fuse.c
> index e01f450..df47c3d 100644
> --- a/lib/fuse.c
> +++ b/lib/fuse.c
> @@ -49,32 +49,6 @@
>
> #define NODE_TABLE_MIN_SIZE 8192
>
> -struct fuse_config {
> - unsigned int uid;
> - unsigned int gid;
> - unsigned int umask;
> - double entry_timeout;
> - double negative_timeout;
> - double attr_timeout;
> - double ac_attr_timeout;
> - int ac_attr_timeout_set;
> - int remember;
> - int nopath;
> - int debug;
> - int hard_remove;
> - int use_ino;
> - int readdir_ino;
> - int set_mode;
> - int set_uid;
> - int set_gid;
> - int direct_io;
> - int kernel_cache;
> - int auto_cache;
> - int intr;
> - int intr_signal;
> - int help;
> - char *modules;
> -};
>
> struct fuse_fs {
> struct fuse_operations op;
> @@ -94,13 +68,6 @@ struct lock_queue_element {
> pthread_cond_t cond;
> };
>
> -struct node_table {
> - struct node **array;
> - size_t use;
> - size_t size;
> - size_t split;
> -};
> -
> #define container_of(ptr, type, member) ({ \
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> (type *)( (char *)__mptr - offsetof(type,member) );})
> @@ -108,38 +75,12 @@ struct node_table {
> #define list_entry(ptr, type, member) \
> container_of(ptr, type, member)
>
> -struct list_head {
> - struct list_head *next;
> - struct list_head *prev;
> -};
> -
> struct node_slab {
> struct list_head list; /* must be the first member */
> struct list_head freelist;
> int used;
> };
>
> -struct fuse {
> - struct fuse_session *se;
> - struct node_table name_table;
> - struct node_table id_table;
> - struct list_head lru_table;
> - fuse_ino_t ctr;
> - unsigned int generation;
> - unsigned int hidectr;
> - pthread_mutex_t lock;
> - struct fuse_config conf;
> - int intr_installed;
> - struct fuse_fs *fs;
> - int nullpath_ok;
> - int curr_ticket;
> - struct lock_queue_element *lockq;
> - int pagesize;
> - struct list_head partial_slabs;
> - struct list_head full_slabs;
> - pthread_t prune_thread;
> -};
> -
> struct lock {
> int type;
> off_t start;
> @@ -4209,6 +4150,12 @@ void fuse_exit(struct fuse *f)
> fuse_session_exit(f->se);
> }
>
> +void fuse_terminate(struct fuse *f)
> +{
> + fuse_session_exit(f->se);
> + pthread_kill(f->main_thread, SIGTERM);
> +}
> +
> struct fuse_context *fuse_get_context(void)
> {
> return &fuse_get_context_internal()->ctx;
> diff --git a/lib/fuse_i.h b/lib/fuse_i.h
> index 78f1467..2759e37 100644
> --- a/lib/fuse_i.h
> +++ b/lib/fuse_i.h
> @@ -58,6 +58,67 @@ struct fuse_notify_req {
> struct fuse_notify_req *prev;
> };
>
> +struct fuse_config {
> + unsigned int uid;
> + unsigned int gid;
> + unsigned int umask;
> + double entry_timeout;
> + double negative_timeout;
> + double attr_timeout;
> + double ac_attr_timeout;
> + int ac_attr_timeout_set;
> + int remember;
> + int nopath;
> + int debug;
> + int hard_remove;
> + int use_ino;
> + int readdir_ino;
> + int set_mode;
> + int set_uid;
> + int set_gid;
> + int direct_io;
> + int kernel_cache;
> + int auto_cache;
> + int intr;
> + int intr_signal;
> + int help;
> + char *modules;
> +};
> +
> +struct list_head {
> + struct list_head *next;
> + struct list_head *prev;
> +};
> +
> +struct node_table {
> + struct node **array;
> + size_t use;
> + size_t size;
> + size_t split;
> +};
> +
> +struct fuse {
> + struct fuse_session *se;
> + struct node_table name_table;
> + struct node_table id_table;
> + struct list_head lru_table;
> + fuse_ino_t ctr;
> + unsigned int generation;
> + unsigned int hidectr;
> + pthread_mutex_t lock;
> + struct fuse_config conf;
> + int intr_installed;
> + struct fuse_fs *fs;
> + int nullpath_ok;
> + int curr_ticket;
> + struct lock_queue_element *lockq;
> + int pagesize;
> + struct list_head partial_slabs;
> + struct list_head full_slabs;
> + pthread_t prune_thread;
> + pthread_t main_thread;
> +};
> +
> struct fuse_ll {
> int debug;
> int allow_root;
> diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
> index 95bc7d9..5314730 100644
> --- a/lib/fuse_versionscript
> +++ b/lib/fuse_versionscript
> @@ -196,6 +196,7 @@ FUSE_2.9 {
> fuse_clean_cache;
> fuse_reply_mmap;
> fuse_lowlevel_notify_delete;
> + fuse_terminate;
>
> local:
> *;
> diff --git a/lib/helper.c b/lib/helper.c
> index ace19dd..e34491c 100644
> --- a/lib/helper.c
> +++ b/lib/helper.c
> @@ -301,6 +301,8 @@ struct fuse *fuse_setup_common(int argc, char *argv[],
> if (fd)
> *fd = fuse_chan_fd(ch);
>
> + fuse->main_thread = pthread_self();
> +
> return fuse;
>
> err_unmount:
I tried it out, but I ran into the following issues:
- I don't go through fuse_setup_common() (I use fuse_mount();
fuse_new(); then pthread_create a new thread to do fuse_loop()), so
main_thread was never set, resulting in a crash.
- If instead I explicitly set main_thread to my thread that does
fuse_loop(), fuse will terminate on fuse_terminate(), but my process
is already checking for SIGTERM and shuts down as a result. I could
probably reconfigure things to ignore this SIGTERM, but I don't know
if it is worth the effort.
So for me it is not so useful - I am content to continue using the
system(fusermount) way that I do now. I can't speak for the original
poster though. Maybe he is doing things slightly different.
I do think the extra clarification in the comment of fuse_exit() would
be helpful either way.
Thanks!
-Mike
|