Commit 28432466f3a80e4d267754f426436c92c58921b5

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent 492efabd

slirp: Enable multi-instance support for the smb service

Push the smb state, smb_dir, into SlirpState and construct it in a way
that allows multiple smb instances (one per slirp stack). Remove the smb
directory on slirp cleanup instead of qemu termination. As VLAN clients
are also cleaned up on process termination, no feature is lost.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 1 changed file with 30 additions and 20 deletions
@@ -681,6 +681,9 @@ typedef struct SlirpState { @@ -681,6 +681,9 @@ typedef struct SlirpState {
681 TAILQ_ENTRY(SlirpState) entry; 681 TAILQ_ENTRY(SlirpState) entry;
682 VLANClientState *vc; 682 VLANClientState *vc;
683 Slirp *slirp; 683 Slirp *slirp;
  684 +#ifndef _WIN32
  685 + char smb_dir[128];
  686 +#endif
684 } SlirpState; 687 } SlirpState;
685 688
686 static struct slirp_config_str *slirp_configs; 689 static struct slirp_config_str *slirp_configs;
@@ -699,6 +702,9 @@ static const char *legacy_smb_export; @@ -699,6 +702,9 @@ static const char *legacy_smb_export;
699 702
700 static void slirp_smb(SlirpState *s, Monitor *mon, const char *exported_dir, 703 static void slirp_smb(SlirpState *s, Monitor *mon, const char *exported_dir,
701 struct in_addr vserver_addr); 704 struct in_addr vserver_addr);
  705 +static void slirp_smb_cleanup(SlirpState *s);
  706 +#else
  707 +static inline void slirp_smb_cleanup(SlirpState *s) { }
702 #endif 708 #endif
703 709
704 int slirp_can_output(void *opaque) 710 int slirp_can_output(void *opaque)
@@ -736,6 +742,7 @@ static void net_slirp_cleanup(VLANClientState *vc) @@ -736,6 +742,7 @@ static void net_slirp_cleanup(VLANClientState *vc)
736 SlirpState *s = vc->opaque; 742 SlirpState *s = vc->opaque;
737 743
738 slirp_cleanup(s->slirp); 744 slirp_cleanup(s->slirp);
  745 + slirp_smb_cleanup(s);
739 TAILQ_REMOVE(&slirp_stacks, s, entry); 746 TAILQ_REMOVE(&slirp_stacks, s, entry);
740 qemu_free(s); 747 qemu_free(s);
741 } 748 }
@@ -1012,35 +1019,38 @@ void net_slirp_redir(const char *redir_str) @@ -1012,35 +1019,38 @@ void net_slirp_redir(const char *redir_str)
1012 1019
1013 #ifndef _WIN32 1020 #ifndef _WIN32
1014 1021
1015 -static char smb_dir[1024];  
1016 -  
1017 /* automatic user mode samba server configuration */ 1022 /* automatic user mode samba server configuration */
1018 -static void smb_exit(void) 1023 +static void slirp_smb_cleanup(SlirpState *s)
1019 { 1024 {
1020 - char cmd[1024]; 1025 + char cmd[128];
1021 1026
1022 - snprintf(cmd, sizeof(cmd), "rm -rf %s", smb_dir);  
1023 - system(cmd); 1027 + if (s->smb_dir[0] != '\0') {
  1028 + snprintf(cmd, sizeof(cmd), "rm -rf %s", s->smb_dir);
  1029 + system(cmd);
  1030 + s->smb_dir[0] = '\0';
  1031 + }
1024 } 1032 }
1025 1033
1026 static void slirp_smb(SlirpState* s, Monitor *mon, const char *exported_dir, 1034 static void slirp_smb(SlirpState* s, Monitor *mon, const char *exported_dir,
1027 struct in_addr vserver_addr) 1035 struct in_addr vserver_addr)
1028 { 1036 {
1029 - char smb_conf[1024];  
1030 - char smb_cmdline[1024]; 1037 + static int instance;
  1038 + char smb_conf[128];
  1039 + char smb_cmdline[128];
1031 FILE *f; 1040 FILE *f;
1032 1041
1033 - /* XXX: better tmp dir construction */  
1034 - snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%ld", (long)getpid());  
1035 - if (mkdir(smb_dir, 0700) < 0) {  
1036 - config_error(mon, "could not create samba server dir '%s'\n", smb_dir); 1042 + snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.%ld-%d",
  1043 + (long)getpid(), instance++);
  1044 + if (mkdir(s->smb_dir, 0700) < 0) {
  1045 + config_error(mon, "could not create samba server dir '%s'\n",
  1046 + s->smb_dir);
1037 return; 1047 return;
1038 } 1048 }
1039 - snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf"); 1049 + snprintf(smb_conf, sizeof(smb_conf), "%s/%s", s->smb_dir, "smb.conf");
1040 1050
1041 f = fopen(smb_conf, "w"); 1051 f = fopen(smb_conf, "w");
1042 if (!f) { 1052 if (!f) {
1043 - smb_exit(); 1053 + slirp_smb_cleanup(s);
1044 config_error(mon, "could not create samba server " 1054 config_error(mon, "could not create samba server "
1045 "configuration file '%s'\n", smb_conf); 1055 "configuration file '%s'\n", smb_conf);
1046 return; 1056 return;
@@ -1059,20 +1069,20 @@ static void slirp_smb(SlirpState* s, Monitor *mon, const char *exported_dir, @@ -1059,20 +1069,20 @@ static void slirp_smb(SlirpState* s, Monitor *mon, const char *exported_dir,
1059 "path=%s\n" 1069 "path=%s\n"
1060 "read only=no\n" 1070 "read only=no\n"
1061 "guest ok=yes\n", 1071 "guest ok=yes\n",
1062 - smb_dir,  
1063 - smb_dir,  
1064 - smb_dir,  
1065 - smb_dir,  
1066 - smb_dir, 1072 + s->smb_dir,
  1073 + s->smb_dir,
  1074 + s->smb_dir,
  1075 + s->smb_dir,
  1076 + s->smb_dir,
1067 exported_dir 1077 exported_dir
1068 ); 1078 );
1069 fclose(f); 1079 fclose(f);
1070 - atexit(smb_exit);  
1071 1080
1072 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s", 1081 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
1073 SMBD_COMMAND, smb_conf); 1082 SMBD_COMMAND, smb_conf);
1074 1083
1075 if (slirp_add_exec(s->slirp, 0, smb_cmdline, vserver_addr, 139) < 0) { 1084 if (slirp_add_exec(s->slirp, 0, smb_cmdline, vserver_addr, 139) < 0) {
  1085 + slirp_smb_cleanup(s);
1076 config_error(mon, "conflicting/invalid smbserver address\n"); 1086 config_error(mon, "conflicting/invalid smbserver address\n");
1077 } 1087 }
1078 } 1088 }