mirror of
https://github.com/clearlinux/clr-debug-info.git
synced 2026-09-06 13:51:38 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b802948209 | ||
|
|
4495b923a9 | ||
|
|
8f7289f028 | ||
|
|
dc376d5e8b | ||
|
|
c831ecb902 | ||
|
|
0978d429b2 | ||
|
|
6653992aba | ||
|
|
0af0308dd2 | ||
|
|
8ace503438 | ||
|
|
2c87f83adc | ||
|
|
67b9b3acc8 | ||
|
|
d108c0af64 | ||
|
|
98e802b4cc | ||
|
|
612801b0c8 | ||
|
|
3c2ad26baa | ||
|
|
d20d585e5c | ||
|
|
1f3a0f0be4 | ||
|
|
d2d67bdb1d | ||
|
|
60db7bab0f | ||
|
|
ef6b11498a | ||
|
|
efeed3e83f | ||
|
|
f5542e7fbb | ||
|
|
be8a99da53 | ||
|
|
c9304402e2 | ||
|
|
6e202f13f7 | ||
|
|
6735f8f6ed | ||
|
|
8b3777ab99 | ||
|
|
84350939ef |
@@ -8,6 +8,7 @@ clr_debug_prepare
|
|||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
|
ar-lib
|
||||||
autom4te.cache/
|
autom4te.cache/
|
||||||
compile
|
compile
|
||||||
config.h
|
config.h
|
||||||
|
|||||||
+5
-4
@@ -1,4 +1,4 @@
|
|||||||
EXTRA_DIST = COPYING clr_debug_fuse.service clr_debug_daemon.service debuginfo.conf
|
EXTRA_DIST = COPYING clr_debug_fuse.service clr_debug_daemon.service clr_debug_daemon.socket debuginfo.conf
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = \
|
DISTCHECK_CONFIGURE_FLAGS = \
|
||||||
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) \
|
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) \
|
||||||
@@ -33,15 +33,16 @@ clr_debug_fuse_SOURCES = src/fuse.c src/client.c
|
|||||||
clr_debug_daemon_SOURCES = src/server.c
|
clr_debug_daemon_SOURCES = src/server.c
|
||||||
clr_debug_daemon_CFLAGS = \
|
clr_debug_daemon_CFLAGS = \
|
||||||
-pthread \
|
-pthread \
|
||||||
$(AM_CFLAGS)
|
$(AM_CFLAGS) \
|
||||||
|
$(LIBSYSTEMD_CFLAGS)
|
||||||
|
|
||||||
clr_debug_prepare_SOURCES = src/prepare.c
|
clr_debug_prepare_SOURCES = src/prepare.c
|
||||||
|
|
||||||
|
|
||||||
clr_debug_fuse_LDADD = ${fuse_LIBS} libnica.la
|
clr_debug_fuse_LDADD = ${fuse_LIBS} libnica.la
|
||||||
clr_debug_daemon_LDADD = ${curl_LIBS} libnica.la
|
clr_debug_daemon_LDADD = ${curl_LIBS} libnica.la ${LIBSYSTEMD_LIBS}
|
||||||
clr_debug_prepare_LDADD = libnica.la
|
clr_debug_prepare_LDADD = libnica.la
|
||||||
|
|
||||||
systemdsystemunit_DATA = clr_debug_fuse.service clr_debug_daemon.service
|
systemdsystemunit_DATA = clr_debug_fuse.service clr_debug_daemon.service clr_debug_daemon.socket
|
||||||
|
|
||||||
tmpfiles_DATA = debuginfo.conf
|
tmpfiles_DATA = debuginfo.conf
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Clear Linux debuginfo daemon
|
Description=Clear Linux debuginfo daemon
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Clear Linux OS debuginfo daemon
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=/run/clr-debug-info
|
||||||
|
SocketMode=0600
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Clear Linux debuginfo fuse monitor
|
Description=Clear Linux debuginfo fuse monitor
|
||||||
After=clr_debug_daemon.service
|
After=clr_debug_daemon.socket
|
||||||
|
Requires=clr_debug_daemon.socket
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
|||||||
+5
-1
@@ -2,17 +2,21 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ([2.66])
|
AC_PREREQ([2.66])
|
||||||
AC_INIT(clr-debug-info, 33, arjan@linux.intel.com)
|
AC_INIT(clr-debug-info, 49, arjan@linux.intel.com)
|
||||||
AM_INIT_AUTOMAKE([foreign -Wall -W subdir-objects])
|
AM_INIT_AUTOMAKE([foreign -Wall -W subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
AM_PROG_AR
|
||||||
AC_LANG(C)
|
AC_LANG(C)
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
PKG_CHECK_MODULES([curl], [libcurl])
|
PKG_CHECK_MODULES([curl], [libcurl])
|
||||||
PKG_CHECK_MODULES([fuse], [fuse])
|
PKG_CHECK_MODULES([fuse], [fuse])
|
||||||
PKG_CHECK_MODULES([SYSTEMD], [systemd])
|
PKG_CHECK_MODULES([SYSTEMD], [systemd])
|
||||||
|
PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd])
|
||||||
LT_INIT
|
LT_INIT
|
||||||
|
|
||||||
|
AC_DEFINE([SOCKET_PATH], ["/run/clr-debug-info"], [path to communication socket])
|
||||||
|
|
||||||
dir=""
|
dir=""
|
||||||
AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
|
AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
|
||||||
[path to systemd system service dir @<:@default=/usr/lib/systemd/system@:>@]), [dir=${withval}],
|
[path to systemd system service dir @<:@default=/usr/lib/systemd/system@:>@]), [dir=${withval}],
|
||||||
|
|||||||
+4
-2
@@ -8,5 +8,7 @@
|
|||||||
# See tmpfiles.d(5) for details
|
# See tmpfiles.d(5) for details
|
||||||
|
|
||||||
# Clear tmp directories separately, to make them easier to override
|
# Clear tmp directories separately, to make them easier to override
|
||||||
d /var/cache/debuginfo/lib 755 root root 10d
|
# Unfortunatly tmpfiles doesn't change the ownership for things if they
|
||||||
d /var/cache/debuginfo/src 755 root root 1d
|
# are not listed.
|
||||||
|
d /var/cache/debuginfo/lib 755 dbginfo dbginfo 10d
|
||||||
|
d /var/cache/debuginfo/src 755 dbginfo dbginfo 1d
|
||||||
|
|||||||
+8
-7
@@ -36,9 +36,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
/* 0.75 seconds timeout */
|
/* 0.75 seconds timeout */
|
||||||
#define TIMEOUT 750000
|
#define TIMEOUT 75000
|
||||||
#define TIMEOUT2 15000
|
#define TIMEOUT2 1500
|
||||||
#define TIMEOUT3 500
|
#define TIMEOUT3 500
|
||||||
|
|
||||||
char *prefix = "src";
|
char *prefix = "src";
|
||||||
@@ -58,7 +60,7 @@ void try_to_get(const char *path, int pid, time_t timestamp)
|
|||||||
int shorttime = 0;
|
int shorttime = 0;
|
||||||
__nc_unused__ size_t wr = -1;
|
__nc_unused__ size_t wr = -1;
|
||||||
|
|
||||||
// printf("Trying to aquire %s\n", path);
|
// printf("Trying to aquire %s\n", path);
|
||||||
|
|
||||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (sockfd < 0) {
|
if (sockfd < 0) {
|
||||||
@@ -66,14 +68,13 @@ void try_to_get(const char *path, int pid, time_t timestamp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sun.sun_family = AF_UNIX;
|
sun.sun_family = AF_UNIX;
|
||||||
strcpy(sun.sun_path, ":clr-debug-info");
|
strcpy(sun.sun_path, SOCKET_PATH);
|
||||||
sun.sun_path[0] = 0; /* anonymous unix socket */
|
|
||||||
|
|
||||||
ret = connect(sockfd,
|
ret = connect(sockfd,
|
||||||
(struct sockaddr *)&sun,
|
(struct sockaddr *)&sun,
|
||||||
offsetof(struct sockaddr_un, sun_path) + strlen(":clr-debug-info") + 1);
|
offsetof(struct sockaddr_un, sun_path) + strlen(SOCKET_PATH) + 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("Cannot connect %s\n", strerror(errno));
|
printf("Cannot connect to %s: %s\n", SOCKET_PATH, strerror(errno));
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -75,6 +75,16 @@ static int xmp_getattr(const char *path, struct stat *stbuf)
|
|||||||
memset(stbuf, 0, sizeof(struct stat));
|
memset(stbuf, 0, sizeof(struct stat));
|
||||||
res = lstat(newpath, stbuf);
|
res = lstat(newpath, stbuf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* filter out things that never should get fetched
|
||||||
|
* this prevents us from asking curl to fetch us useless things
|
||||||
|
*/
|
||||||
|
if (strncmp(path, "/.Trash", strlen("/.Trash")) == 0) {
|
||||||
|
return -ENOENT;
|
||||||
|
} else if (strcmp(path, "/") == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the file. if the st_mtime is set, this is just an async refresh, otherwise it's
|
* get the file. if the st_mtime is set, this is just an async refresh, otherwise it's
|
||||||
* a synchronous request.
|
* a synchronous request.
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@ bool nc_copy_file(const char *src, const char *dst, mode_t mode, bool remove_tar
|
|||||||
while (true) {
|
while (true) {
|
||||||
if ((r = read(src_fd, &buffer, sizeof(buffer))) < 0) {
|
if ((r = read(src_fd, &buffer, sizeof(buffer))) < 0) {
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
goto end;
|
||||||
}
|
}
|
||||||
if (write(dest_fd, buffer, sizeof(buffer)) != r) {
|
if (write(dest_fd, buffer, sizeof(buffer)) != r) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
+7
-5
@@ -123,8 +123,8 @@ static inline unsigned nc_hashmap_get_hash(NcHashmap *self, const void *key)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool nc_hashmap_insert_bucket(NcHashmap *self, NcHashmapEntry *buckets, int n_buckets,
|
static int nc_hashmap_insert_bucket(NcHashmap *self, NcHashmapEntry *buckets, int n_buckets,
|
||||||
unsigned hash, const void *key, void *value)
|
unsigned hash, const void *key, void *value)
|
||||||
{
|
{
|
||||||
NcHashmapEntry *row = &(buckets[hash % n_buckets]);
|
NcHashmapEntry *row = &(buckets[hash % n_buckets]);
|
||||||
NcHashmapEntry *head = NULL;
|
NcHashmapEntry *head = NULL;
|
||||||
@@ -458,10 +458,12 @@ bool nc_hashmap_iter_next(NcHashmapIter *citer, void **key, void **value)
|
|||||||
}
|
}
|
||||||
item = &(map->buckets[iter->bucket]);
|
item = &(map->buckets[iter->bucket]);
|
||||||
}
|
}
|
||||||
if (item && item->occ) {
|
if (item) {
|
||||||
goto success;
|
if (item->occ) {
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
item = item->next;
|
||||||
}
|
}
|
||||||
item = item->next;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
+151
-41
@@ -2,7 +2,7 @@
|
|||||||
* Clear Linux -- automatic debug information installation
|
* Clear Linux -- automatic debug information installation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Arjan van de Ven
|
* Copyright (C) 2013 Arjan van de Ven
|
||||||
* Curl portions borrowed from the Fenrus Update code
|
* Curl portions borrowed from the Fenrus Update code
|
||||||
* which in part is (C) 2012 Intel Corporation
|
* which in part is (C) 2012 Intel Corporation
|
||||||
* Copyright (C) 2014 Intel Corporation
|
* Copyright (C) 2014 Intel Corporation
|
||||||
*
|
*
|
||||||
@@ -27,9 +27,12 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -47,16 +50,20 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "systemd/sd-daemon.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef HAVE_ATOMIC_SUPPORT
|
#ifdef HAVE_ATOMIC_SUPPORT
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TIMEOUT 600 /* 10 minutes */
|
||||||
|
|
||||||
static pthread_mutex_t dupes_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t dupes_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
char *urls[2] = { "https://cdn.download.clearlinux.org/debuginfo/",
|
char *urls[2] = { "https://cdn.download.clearlinux.org/debuginfo/",
|
||||||
"https://cdn.download.clearlinux.org/debuginfo/" };
|
"https://cdn-alt.download.clearlinux.org/debuginfo/" };
|
||||||
int urlcounter = 1;
|
int urlcounter = 1;
|
||||||
|
|
||||||
static NcHashmap *hash = NULL;
|
static NcHashmap *hash = NULL;
|
||||||
@@ -162,11 +169,11 @@ static int curl_get_file(const char *url, const char *prefix, time_t timestamp)
|
|||||||
{
|
{
|
||||||
CURLcode code;
|
CURLcode code;
|
||||||
long ret;
|
long ret;
|
||||||
|
long changed;
|
||||||
int fd;
|
int fd;
|
||||||
char filename[PATH_MAX];
|
autofree(char) *filename = NULL;
|
||||||
CURL *curl = NULL;
|
CURL *curl = NULL;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
struct stat statbuf;
|
|
||||||
|
|
||||||
if (avoid_dupes(url)) {
|
if (avoid_dupes(url)) {
|
||||||
return 300;
|
return 300;
|
||||||
@@ -177,12 +184,15 @@ static int curl_get_file(const char *url, const char *prefix, time_t timestamp)
|
|||||||
return 301;
|
return 301;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(filename, "/tmp/clr-debug-info-XXXXXX");
|
// fprintf(stderr, "Fetching %s, prefix %s, path %s\n", url, prefix, path);
|
||||||
|
if (asprintf(&filename, "/tmp/clr-debug-info-XXXXXX") < 0) {
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
return 418;
|
||||||
|
}
|
||||||
fd = mkstemp(filename);
|
fd = mkstemp(filename);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
return 500;
|
return 418;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = fdopen(fd, "w");
|
file = fdopen(fd, "w");
|
||||||
@@ -203,6 +213,9 @@ static int curl_get_file(const char *url, const char *prefix, time_t timestamp)
|
|||||||
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 30);
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 30);
|
||||||
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1024);
|
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1024);
|
||||||
|
|
||||||
|
/* request timestamp of files from server */
|
||||||
|
curl_easy_setopt(curl, CURLOPT_FILETIME, 1);
|
||||||
|
|
||||||
if (timestamp) {
|
if (timestamp) {
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, timestamp);
|
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, timestamp);
|
||||||
@@ -217,7 +230,7 @@ static int curl_get_file(const char *url, const char *prefix, time_t timestamp)
|
|||||||
|
|
||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &ret);
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &ret);
|
||||||
fflush(file);
|
fflush(file);
|
||||||
// printf("HTTP return code is %i\n", ret);
|
// printf("HTTP return code is %i\n", ret);
|
||||||
|
|
||||||
/* HTTP 304 is returned if (a) the cached debuginfo has the same
|
/* HTTP 304 is returned if (a) the cached debuginfo has the same
|
||||||
* timestamp or is newer than that on the server and (b) we haven't
|
* timestamp or is newer than that on the server and (b) we haven't
|
||||||
@@ -231,20 +244,58 @@ static int curl_get_file(const char *url, const char *prefix, time_t timestamp)
|
|||||||
|
|
||||||
if (ret == 200) {
|
if (ret == 200) {
|
||||||
autofree(char) *command = NULL;
|
autofree(char) *command = NULL;
|
||||||
// printf("Filename is %s\n", filename);
|
struct stat statbuf;
|
||||||
|
|
||||||
|
/* get timestamp, if any */
|
||||||
|
curl_easy_getinfo(curl, CURLINFO_FILETIME, &changed);
|
||||||
|
if (changed >= 0) {
|
||||||
|
struct timespec times[2];
|
||||||
|
times[0].tv_sec = (time_t)changed;
|
||||||
|
times[0].tv_nsec = 0;
|
||||||
|
times[1].tv_sec = (time_t)changed;
|
||||||
|
times[1].tv_nsec = 0;
|
||||||
|
futimens(fd, times);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&statbuf, 0, sizeof(statbuf));
|
memset(&statbuf, 0, sizeof(statbuf));
|
||||||
stat(filename, &statbuf);
|
stat(filename, &statbuf);
|
||||||
if (statbuf.st_size > 0 &&
|
if (statbuf.st_size <= 0) {
|
||||||
asprintf(&command,
|
ret = 418;
|
||||||
"tar -C /var/cache/debuginfo/%s --no-same-owner --no-same-permissions -xf %s",
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test extraction first */
|
||||||
|
if (asprintf(&command, "tar -C /var/cache/debuginfo/%s --no-same-owner "
|
||||||
|
"--no-same-permissions -tf %s",
|
||||||
prefix,
|
prefix,
|
||||||
filename) >= 0) {
|
filename) < 0) {
|
||||||
if (system(command) != 0) {
|
ret = 418;
|
||||||
fputs("Warning: tar extraction failed\n", stderr);
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (system(command) != 0) {
|
||||||
|
ret = 418;
|
||||||
|
fprintf(stderr, "Error: tar validation failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(command); /* reuse */
|
||||||
|
if (asprintf(&command, "tar -C /var/cache/debuginfo/%s --no-same-owner "
|
||||||
|
"--no-same-permissions -xf %s",
|
||||||
|
prefix,
|
||||||
|
filename) < 0) {
|
||||||
|
ret = 418;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system(command) != 0) {
|
||||||
|
ret = 418;
|
||||||
|
fprintf(stderr, "Error: tar extraction failed\n");
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@@ -282,7 +333,6 @@ static void *server_thread(void *arg)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto thread_end;
|
goto thread_end;
|
||||||
}
|
}
|
||||||
prefix = buf;
|
|
||||||
c = strchr(buf, ':');
|
c = strchr(buf, ':');
|
||||||
if (!c) {
|
if (!c) {
|
||||||
goto thread_end;
|
goto thread_end;
|
||||||
@@ -319,7 +369,7 @@ static void *server_thread(void *arg)
|
|||||||
goto thread_end;
|
goto thread_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("Getting url %s %i:%06i\n", url, before.tv_sec, before.tv_usec);
|
// printf("Getting url %s %i:%06i\n", url, before.tv_sec, before.tv_usec);
|
||||||
ret = curl_get_file(url, prefix, timestamp);
|
ret = curl_get_file(url, prefix, timestamp);
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
@@ -330,12 +380,12 @@ static void *server_thread(void *arg)
|
|||||||
// ignore these error codes
|
// ignore these error codes
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Request for %s resulted in error %i\n", url, ret);
|
fprintf(stderr, "Request for %s resulted in error %i\n", url, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gettimeofday(&after, NULL);
|
gettimeofday(&after, NULL);
|
||||||
#if 0
|
#if 0
|
||||||
if (timedelta(before, after) > 0.6)
|
if (timedelta(before, after) > 0.6)
|
||||||
printf("Request for %s took %5.2f seconds (%i - %i)\n",
|
printf("Request for %s took %5.2f seconds (%i - %i)\n",
|
||||||
url,
|
url,
|
||||||
@@ -361,8 +411,19 @@ int main(__nc_unused__ int argc, __nc_unused__ char **argv)
|
|||||||
struct sockaddr_un sun;
|
struct sockaddr_un sun;
|
||||||
int ret;
|
int ret;
|
||||||
int curl_done = 0;
|
int curl_done = 0;
|
||||||
|
uid_t dbg_user = 0;
|
||||||
|
gid_t dbg_group = 0;
|
||||||
|
struct passwd *passwdentry;
|
||||||
const char *required_paths[] = { "/var/cache/debuginfo/lib", "/var/cache/debuginfo/src" };
|
const char *required_paths[] = { "/var/cache/debuginfo/lib", "/var/cache/debuginfo/src" };
|
||||||
|
|
||||||
|
umask(0);
|
||||||
|
passwdentry = getpwnam("dbginfo");
|
||||||
|
if (passwdentry) {
|
||||||
|
dbg_user = passwdentry->pw_uid;
|
||||||
|
dbg_group = passwdentry->pw_gid;
|
||||||
|
}
|
||||||
|
endpwent();
|
||||||
|
|
||||||
if (prctl(PR_SET_DUMPABLE, 0) != 0) {
|
if (prctl(PR_SET_DUMPABLE, 0) != 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Failed to disable PR_SET_DUMPABLE. Do NOT gdb attach this process: %s\n",
|
"Failed to disable PR_SET_DUMPABLE. Do NOT gdb attach this process: %s\n",
|
||||||
@@ -377,44 +438,95 @@ int main(__nc_unused__ int argc, __nc_unused__ char **argv)
|
|||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(required_paths); i++) {
|
for (size_t i = 0; i < ARRAY_SIZE(required_paths); i++) {
|
||||||
const char *req_path = required_paths[i];
|
const char *req_path = required_paths[i];
|
||||||
if (nc_file_exists(req_path)) {
|
struct stat st = { .st_ino = 0 };
|
||||||
continue;
|
if (lstat(req_path, &st) == 0) {
|
||||||
|
/* If the file already exists, check ownership
|
||||||
|
* and delete tree if incorrect. Essentially a
|
||||||
|
* one-off operation to transition from root owned to
|
||||||
|
* dbginfo owned */
|
||||||
|
if (st.st_uid == dbg_user) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Removing old debug information %s\n", req_path);
|
||||||
|
nc_rm_rf(req_path);
|
||||||
}
|
}
|
||||||
if (!nc_mkdir_p(req_path, 00755)) {
|
if (!nc_mkdir_p(req_path, 00755)) {
|
||||||
fprintf(stderr, "Failed to mkdir: %s %s\n", strerror(errno), req_path);
|
fprintf(stderr, "Failed to mkdir: %s %s\n", strerror(errno), req_path);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
if (chown(req_path, dbg_user, dbg_group) != 0) {
|
||||||
|
fprintf(stderr, "Failed to chown: %s %s\n", strerror(errno), req_path);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
if (sd_listen_fds(0) == 1) {
|
||||||
if (sockfd < 0) {
|
/* systemd socket activation */
|
||||||
return EXIT_FAILURE;
|
sockfd = SD_LISTEN_FDS_START + 0;
|
||||||
|
} else if (sd_listen_fds(0) > 1) {
|
||||||
|
fprintf(stderr, "Too many file descriptors received.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (sockfd < 0) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sun.sun_family = AF_UNIX;
|
||||||
|
strcpy(sun.sun_path, SOCKET_PATH);
|
||||||
|
|
||||||
|
ret = bind(sockfd,
|
||||||
|
(struct sockaddr *)&sun,
|
||||||
|
offsetof(struct sockaddr_un, sun_path) + strlen(SOCKET_PATH) + 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Failed to bind:%s \n", strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(sockfd, 16) < 0) {
|
||||||
|
fprintf(stderr, "Failed to listen:%s \n", strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sun.sun_family = AF_UNIX;
|
if (setgid(dbg_group)) {
|
||||||
strcpy(sun.sun_path, ":clr-debug-info");
|
fprintf(stderr, "Unable to drop privileges setgid %s\n", strerror(errno));
|
||||||
sun.sun_path[0] = 0; /* anonymous unix socket */
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
ret = bind(sockfd,
|
|
||||||
(struct sockaddr *)&sun,
|
|
||||||
offsetof(struct sockaddr_un, sun_path) + strlen(":clr-debug-info") + 1);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("Failed to bind:%s \n", strerror(errno));
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
if (setgroups(1, &dbg_group)) {
|
||||||
if (listen(sockfd, 16) < 0) {
|
fprintf(stderr, "Unable to drop privileges setgroups %s\n", strerror(errno));
|
||||||
printf("Failed to listen:%s \n", strerror(errno));
|
exit(EXIT_FAILURE);
|
||||||
return EXIT_FAILURE;
|
}
|
||||||
|
if (setuid(dbg_user)) {
|
||||||
|
fprintf(stderr, "Unable to drop privileges setuid %s\n", strerror(errno));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int ret;
|
||||||
int clientsock;
|
int clientsock;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
|
|
||||||
malloc_trim(0);
|
malloc_trim(0);
|
||||||
|
|
||||||
|
/* use select() to timeout and exit gracefully */
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(sockfd, &rfds);
|
||||||
|
tv.tv_sec = TIMEOUT;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
ret = select(sockfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("select()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else if (ret == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
clientsock = accept(sockfd, NULL, NULL);
|
clientsock = accept(sockfd, NULL, NULL);
|
||||||
|
|
||||||
/* Too many connections, wait for the next loop/retry */
|
/* Too many connections, wait for the next loop/retry */
|
||||||
@@ -439,6 +551,4 @@ int main(__nc_unused__ int argc, __nc_unused__ char **argv)
|
|||||||
if (hash) {
|
if (hash) {
|
||||||
nc_hashmap_free(hash);
|
nc_hashmap_free(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(sockfd);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user