add support of cifs network install method

This commit is contained in:
Evgeny Sinelnikov 2014-01-11 18:49:44 +04:00 committed by Evgeny Sinelnikov
parent 95bfcf8542
commit 59a9c4de30
6 changed files with 185 additions and 0 deletions

View File

@ -45,6 +45,9 @@ INITOBJS = $(addprefix $(L)-,$(subst .c,.o,$(INITSRC)))
#---------------------------------------------------------------
STAGE1_DEFS =
ifneq ($(WITH_CIFS),)
STAGE1_DEFS += -DENABLE_CIFS
endif
ifneq ($(WITH_SHELL),)
STAGE1_DEFS += -DSPAWN_SHELL
endif

56
mount.c
View File

@ -168,6 +168,53 @@ static int nfsmount(char *dev, char *location)
waitpid(pid, &status, 0);
return (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
}
#ifdef ENABLE_CIFS
static int cifsmount(char *dev, char *location)
{
char spec[PATH_MAX + 19], *sep, *ptr = dev;
struct sockaddr_in saddr;
int n, pid, status;
while (*ptr == '/') ptr++;
if ((sep = strchr(ptr, '/'))) {
*sep = '\0';
} else {
log_message("cifsmount: directory to mount not in //host/dir format");
return -1;
}
saddr.sin_family = AF_INET;
if (!inet_aton(ptr, &saddr.sin_addr) &&
mygethostbyname(ptr, &saddr.sin_addr)) {
log_message("cifsmount: can't get address for %s", ptr);
*sep = '/';
return -1;
}
*sep = '/';
*spec = '\0';
strcpy(spec, "//");
strcat(spec, inet_ntoa(saddr.sin_addr));
n = strlen(spec);
strncpy(spec + n, sep, sizeof(spec) - n);
log_message("cifsmount %s %s", spec, location);
if (!(pid = fork())) {
char * argv[] = {"/sbin/mount.cifs", spec, location, "-oguest", NULL};
close(0);
close(1);
close(2);
execve(argv[0], argv, NULL);
exit(1);
}
waitpid(pid, &status, 0);
return (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1;
}
#endif
#endif
/* mounts, creating the device if needed+possible */
@ -179,7 +226,11 @@ int my_mount(char *dev, char *location, char *fs, int force_rw)
int rc;
#ifndef DISABLE_MEDIAS
#ifdef ENABLE_CIFS
if (strcmp(fs, "nfs") && strcmp(fs, "cifs")) {
#else
if (strcmp(fs, "nfs")) {
#endif
rc = ensure_dev_exists(dev);
if (rc != 0) {
log_message("could not create required device file");
@ -211,6 +262,11 @@ int my_mount(char *dev, char *location, char *fs, int force_rw)
if (!strcmp(fs, "nfs")) {
return nfsmount(dev, location);
}
#ifdef ENABLE_CIFS
if (!strcmp(fs, "cifs")) {
return cifsmount(dev, location);
}
#endif
#endif
#ifndef DISABLE_MEDIAS

112
network.c
View File

@ -769,6 +769,118 @@ enum return_type nfs_prepare(void)
return RETURN_OK;
}
#ifdef ENABLE_CIFS
enum return_type cifs_prepare(void)
{
char * questions[] = { "Samba server name", "Directory", NULL };
char * questions_auto[] = { "server", "directory", NULL };
char msg[256];
static char ** answers = NULL;
char * cifsmount_location;
char * ramdisk_path;
enum return_type results = intf_select_and_up();
struct stat st;
int iso = 0;
if (results != RETURN_OK)
return results;
update_splash("prepare");
do {
snprintf(msg, sizeof(msg), "Please enter the name or IP address of your Samba server, "
"and the directory (or ISO image file) containing the %s Distribution.", version);
results = ask_from_entries_auto(msg, questions, &answers, 40, questions_auto, NULL);
if (results != RETURN_OK || streq(answers[0], "")) {
if (next_server.s_addr && rootpath != NULL) {
log_message("Using params supplied by DHCP");
cifsmount_location = malloc(strlen(rootpath) + 19);
strcpy(cifsmount_location, "//");
strcat(cifsmount_location, inet_ntoa(next_server));
if (rootpath[0] != '/')
strcat(cifsmount_location, "/");
strcat(cifsmount_location, rootpath);
} else {
unset_param(MODE_AUTOMATIC); /* we are in a fallback mode */
return cifs_prepare();
}
} else {
cifsmount_location = malloc(strlen(answers[0]) + strlen(answers[1]) + 4);
strcpy(cifsmount_location, "//");
strcat(cifsmount_location, answers[0]);
if (answers[1][0] != '/')
strcat(cifsmount_location, "/");
strcat(cifsmount_location, answers[1]);
}
if (my_mount(cifsmount_location, IMAGE_LOCATION, "cifs", 0) == -1) {
char location_full[500];
char *s, *r;
/* iso pathname ? */
s = strrchr(cifsmount_location, '/');
r = strchr(cifsmount_location + 2, '/');
if (s == NULL || s == cifsmount_location || s == r) {
stg1_error_message("I can't try to get location of ISO image directory at Samba server.");
results = RETURN_BACK;
continue;
}
*s++ = 0;
log_message("assuming ISO image, Samba path:%s", cifsmount_location);
if (my_mount(cifsmount_location, IMAGE_LOCATION, "cifs", 0) == -1) {
stg1_error_message("I can't mount the directory from the Samba server.");
results = RETURN_BACK;
continue;
}
strcpy(location_full, IMAGE_LOCATION);
strcat(location_full, "/");
strcat(location_full, s);
log_message("assuming ISO image, path:%s", location_full);
if (!stat(location_full, &st) && !S_ISREG(st.st_mode)) {
stg1_error_message("Not a ISO image: %s", location_full);
umount(IMAGE_LOCATION);
results = RETURN_BACK;
continue;
}
if (lomount(location_full, IMAGE_LOCATION)) {
stg1_error_message("Could not mount file %s as an ISO image of the %s Distribution.", location_full, version);
umount(IMAGE_LOCATION);
results = RETURN_BACK;
continue;
}
iso = 1;
add_to_env("PIGGYBACK", "1");
}
ramdisk_path = get_ramdisk_path(NULL);
if (access(ramdisk_path, R_OK)) {
stg1_error_message("That Samba volume does not seem to contain the %s Distribution.", version);
umount(IMAGE_LOCATION);
if (iso) umount(IMAGE_LOCATION);
results = RETURN_BACK;
}
} while (results == RETURN_BACK);
log_message("found the %s Installation, good news!", version);
stat(ramdisk_path, &st);
if (S_ISDIR(st.st_mode)) {
mount(ramdisk_path, STAGE2_LOCATION, NULL, MS_BIND, NULL);
} else {
do_losetup(LIVE_DEVICE,ramdisk_path);
my_mount(LIVE_DEVICE, STAGE2_LOCATION, (IS_LIVE) ? LIVEFS : STAGE2FS, 0);
}
method_name = strdup("cifs");
add_to_env("METHOD", method_name);
add_to_env("HOST", answers[0]);
add_to_env("PREFIX", answers[1]);
update_splash("found_media");
return RETURN_OK;
}
#endif
enum return_type ftp_prepare(void)
{

View File

@ -30,6 +30,7 @@ enum return_type net_prepare(void);
enum return_type nfs_prepare(void);
enum return_type ftp_prepare(void);
enum return_type http_prepare(void);
enum return_type cifs_prepare(void);
enum boot_proto_type { BOOTPROTO_STATIC, BOOTPROTO_DHCP, BOOTPROTO_ADSL_PPPOE };

View File

@ -1,3 +1,4 @@
%def_with cifs
%def_with shell
%def_with splash
@ -23,6 +24,7 @@ including init and various helpers for hw probing and bootstrapping.
%build
%make_build \
%{?_with_cifs:WITH_CIFS=t} \
%{?_with_shell:WITH_SHELL=t} \
%{?_with_splash:WITH_SPLASH=t} \
version=%version-%release \

View File

@ -257,6 +257,9 @@ static enum return_type method_select_and_prepare(void)
char * network_nfs_install = "NFS server"; char * network_nfs_install_auto = "nfs";
char * network_ftp_install = "FTP server"; char * network_ftp_install_auto = "ftp";
char * network_http_install = "HTTP server"; char * network_http_install_auto = "http";
#ifdef ENABLE_CIFS
char * network_cifs_install = "Samba server"; char * network_cifs_install_auto = "cifs";
#endif
#endif
i = 0;
@ -264,6 +267,9 @@ static enum return_type method_select_and_prepare(void)
means[i] = network_nfs_install; means_auto[i++] = network_nfs_install_auto;
means[i] = network_ftp_install; means_auto[i++] = network_ftp_install_auto;
means[i] = network_http_install; means_auto[i++] = network_http_install_auto;
#ifdef ENABLE_CIFS
means[i] = network_cifs_install; means_auto[i++] = network_cifs_install_auto;
#endif
#endif
#ifndef DISABLE_CDROM
means[i] = cdrom_install; means_auto[i++] = cdrom_install_auto;
@ -305,6 +311,11 @@ static enum return_type method_select_and_prepare(void)
if (!strcmp(choice, network_http_install))
results = http_prepare();
#ifdef ENABLE_CIFS
if (!strcmp(choice, network_cifs_install))
results = cifs_prepare();
#endif
#endif
if (results != RETURN_OK)