[IPVS]: Fix state variable on failure to start ipvs threads

ip_vs currently fails to reset its ip_vs_sync_state variable if the
sync thread fails to start properly. The result is that the kernel
will report a running daemon when their actuall is none.

If you issue the following commands:

1. ipvsadm --start-daemon master --mcast-interface bla
2. ipvsadm -L --daemon
3. ipvsadm --stop-daemon master

Assuming that bla is not an actual interface, step 2 should return no
data, but instead returns:

$ ipvsadm -L --daemon
master sync daemon (mcast=bla, syncid=0)

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Neil Horman and committed by David S. Miller cc0191ae 28121617

+39 -2
+39 -2
net/ipv4/ipvs/ip_vs_sync.c
··· 67 struct ip_vs_seq out_seq; /* outgoing seq. struct */ 68 }; 69 70 #define IP_VS_SYNC_CONN_TIMEOUT (3*60*HZ) 71 #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn)) 72 #define FULL_CONN_SIZE \ ··· 756 mm_segment_t oldmm; 757 int state; 758 const char *name; 759 760 /* increase the module use count */ 761 ip_vs_use_count_inc(); ··· 795 add_wait_queue(&sync_wait, &wait); 796 797 set_sync_pid(state, current->pid); 798 - complete((struct completion *)startup); 799 800 /* processing master/backup loop here */ 801 if (state == IP_VS_STATE_MASTER) ··· 814 remove_wait_queue(&sync_wait, &wait); 815 816 /* thread exits */ 817 set_sync_pid(state, 0); 818 IP_VS_INFO("sync thread stopped!\n"); 819 ··· 833 set_stop_sync(state, 0); 834 wake_up(&stop_sync_wait); 835 836 return 0; 837 } 838 ··· 864 { 865 DECLARE_COMPLETION_ONSTACK(startup); 866 pid_t pid; 867 868 if ((state == IP_VS_STATE_MASTER && sync_master_pid) || 869 (state == IP_VS_STATE_BACKUP && sync_backup_pid)) 870 return -EEXIST; 871 872 IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); 873 IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n", ··· 892 ip_vs_backup_syncid = syncid; 893 } 894 895 repeat: 896 - if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) { 897 IP_VS_ERR("could not create fork_sync_thread due to %d... " 898 "retrying.\n", pid); 899 msleep_interruptible(1000);
··· 67 struct ip_vs_seq out_seq; /* outgoing seq. struct */ 68 }; 69 70 + struct ip_vs_sync_thread_data { 71 + struct completion *startup; 72 + int state; 73 + }; 74 + 75 #define IP_VS_SYNC_CONN_TIMEOUT (3*60*HZ) 76 #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn)) 77 #define FULL_CONN_SIZE \ ··· 751 mm_segment_t oldmm; 752 int state; 753 const char *name; 754 + struct ip_vs_sync_thread_data *tinfo = startup; 755 756 /* increase the module use count */ 757 ip_vs_use_count_inc(); ··· 789 add_wait_queue(&sync_wait, &wait); 790 791 set_sync_pid(state, current->pid); 792 + complete(tinfo->startup); 793 + 794 + /* 795 + * once we call the completion queue above, we should 796 + * null out that reference, since its allocated on the 797 + * stack of the creating kernel thread 798 + */ 799 + tinfo->startup = NULL; 800 801 /* processing master/backup loop here */ 802 if (state == IP_VS_STATE_MASTER) ··· 801 remove_wait_queue(&sync_wait, &wait); 802 803 /* thread exits */ 804 + 805 + /* 806 + * If we weren't explicitly stopped, then we 807 + * exited in error, and should undo our state 808 + */ 809 + if ((!stop_master_sync) && (!stop_backup_sync)) 810 + ip_vs_sync_state -= tinfo->state; 811 + 812 set_sync_pid(state, 0); 813 IP_VS_INFO("sync thread stopped!\n"); 814 ··· 812 set_stop_sync(state, 0); 813 wake_up(&stop_sync_wait); 814 815 + /* 816 + * we need to free the structure that was allocated 817 + * for us in start_sync_thread 818 + */ 819 + kfree(tinfo); 820 return 0; 821 } 822 ··· 838 { 839 DECLARE_COMPLETION_ONSTACK(startup); 840 pid_t pid; 841 + struct ip_vs_sync_thread_data *tinfo; 842 843 if ((state == IP_VS_STATE_MASTER && sync_master_pid) || 844 (state == IP_VS_STATE_BACKUP && sync_backup_pid)) 845 return -EEXIST; 846 + 847 + /* 848 + * Note that tinfo will be freed in sync_thread on exit 849 + */ 850 + tinfo = kmalloc(sizeof(struct ip_vs_sync_thread_data), GFP_KERNEL); 851 + if (!tinfo) 852 + return -ENOMEM; 853 854 IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); 855 IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n", ··· 858 ip_vs_backup_syncid = syncid; 859 } 860 861 + tinfo->state = state; 862 + tinfo->startup = &startup; 863 + 864 repeat: 865 + if ((pid = kernel_thread(fork_sync_thread, tinfo, 0)) < 0) { 866 IP_VS_ERR("could not create fork_sync_thread due to %d... " 867 "retrying.\n", pid); 868 msleep_interruptible(1000);